简体   繁体   English

如何在qt中创建自定义TreeView,并将分支放在ItemView的右侧?

[英]How to create a custom TreeView in qt with branches put at right side of the ItemView?

What I want is to create a sidebar with qt with QTreeView that branches are put at right side of items.我想要的是用 QTreeView 创建一个带有 qt 的侧边栏,将分支放在项目的右侧。 Like AdminLTE sidebar: https://adminlte.io/themes/AdminLTE/index2.html# .像 AdminLTE 侧边栏: https ://adminlte.io/themes/AdminLTE/index2.html#。

I have Tried several solutions each failing my desired design:我已经尝试了几种解决方案,但每个都没有达到我想要的设计:

  1. Using delegates使用委托
  2. Deriving TreeView class and reimplement DrawBranches派生 TreeView 类并重新实现 DrawBranches
  3. Create a custom ProxyStyle创建自定义 ProxyStyle

The whole point is I am from a web development background and doing such things is super easy with it!重点是我来自 Web 开发背景,用它做这些事情非常容易!

Edit:编辑:

Supposing we have a stupid ProxyStyle-derived class, what I should do for the situations below:假设我们有一个愚蠢的 ProxyStyle 派生类,我应该为以下情况做些什么:

void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    if (element == PE_IndicatorBranch) {
        // put this damn thing at right
    }
    else if(element == PE_PanelItemViewItem) {
        // put this at left
    }
    // else
    QProxyStyle::drawPrimitive(element, option, painter, widget);
}

or maybe using a delegate:或者可能使用委托:

void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // for example translate branch!? what to do????
    QStyledItemDelegate::paint(painter, option, index);

}

or maybe reimplementing TreeView::DrawBranches.或者重新实现 TreeView::DrawBranches。 Either way, no idea what to do to fully accomplish my requirements.无论哪种方式,都不知道该怎么做才能完全满足我的要求。

Edit2:编辑2:

This is it for now, but still not what I want, for example hovering makes off behavior:现在就是这样,但仍然不是我想要的,例如悬停会导致行为:

sidebar.cpp侧边栏.cpp

#include "sidebar.h"

#include <QMouseEvent>
#include <QPainter>
#include "sidebarstyle.h"
#include "sidebardelegate.h"

SideBar::SideBar(QWidget *parent)
    : QTreeView(parent)
{
    setStyle(new SideBarStyle);
    setItemDelegate(new SideBarDelegate(this));
    setHeaderHidden(true);
    setEditTriggers(QAbstractItemView::NoEditTriggers);
    //    setIndentation(40);
    resize(230, parent->height());
    setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));

    //    QPalette palette;
    //    palette.setBrush(QPalette::Base, QColor(34, 45, 50));
    //    palette.setBrush(QPalette::Highlight, Qt::transparent);
    //    setPalette(palette);
    setStyleSheet("QTreeView::item {height: 50px;} QTreeView {background-color: #222d32; color: #b8c7ce; font-size: 14px; font-weight: 400;} QTreeView::branch:selected, QTreeView::item:selected, QTreeView::branch:hover, QTreeView::item:hover {background-color: #1e282c; color: #fff}");
    //    setStyleSheet("QTreeView {background-color: #222d32; color: #b8c7ce}");


}

void SideBar::mousePressEvent(QMouseEvent *event)
{
    QModelIndex index = indexAt(event->pos());
    bool lastState = isExpanded(index);
    QTreeView::mousePressEvent(event);
    setExpanded(index, !lastState);
}

void SideBar::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const
{
    QTreeView::drawBranches(painter, rect, index);
}

sidebardelegate.cpp sidebardelegate.cpp

#include "sidebardelegate.h"
#include <QPainter>
#include "state.h"

SideBarDelegate::SideBarDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
    font.setFamily("FontAwesome");
    font.setPixelSize(28);

}

void SideBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    QStyledItemDelegate::paint(painter, option, index);
    if(index.column() == 0){
        QRect _branch = QRect(option.widget->width() - option.decorationSize.width() -25, option.rect.y() + option.rect.height() / 4, option.decorationSize.width() + 15, option.rect.height() / 2);
        //        QRect icon = QRect(5, option.rect.y() + option.rect.height() / 4, option.decorationSize.width(), option.rect.height() / 2);
        QModelIndex _index = index;
        int depth = 0;
        while ( _index.parent().isValid() )
        {
            _index = _index.parent();
            depth++;
        }
        //        if(index.parent().isValid()) {
        QRect icon = QRect(5 + option.decorationSize.width() * depth, option.rect.y() + option.rect.height() / 4, option.decorationSize.width() + 10, option.rect.height() / 2);
        //        }
        painter->setFont(font);
        if(option.state & QStyle::State_Children)
        {
            if(option.state & QStyle::State_Open)
            {
                //                painter->drawImage(_branch, QImage("/home/fisher/Pictures/Download.png"));
                painter->drawText(_branch, "\uf107");
            }
            else
            {
                //painter->drawImage(_branch, QImage("/home/fisher/Pictures/135210286.png"));
                painter->drawText(_branch, "\uf104");
            }
            switch (index.row()) {
            case 0:
                //                painter->drawImage(icon, QImage("/home/fisher/Pictures/135210286.png"));
                painter->drawText(icon, "\uf080");
                break;
            case 1:
                //                painter->drawImage(icon, QImage("/home/fisher/Pictures/images.png"));
                painter->drawText(icon, "\uf14a");
                break;
            case 2:
                //                painter->drawImage(icon, QImage("/home/fisher/Pictures/iamges.jpeg"));
                painter->drawText(icon, "\uf0c3");
                break;
            default:
                //                painter->drawImage(icon, QImage("/home/fisher/Pictures/images (1).png"));
                painter->drawText(icon, "\uf085");
            }
            if(option.state & QStyle::State_Selected) {
                QRect bar = QRect(0, option.rect.y(), 2, option.rect.height());
                painter->setBrush(QColor(60, 141, 188));
                painter->setPen(QColor(60, 141, 188));
                painter->drawRect(bar);
            }
        } else {
                        adjustDefaultTextColors(option, *painter);
            painter->drawText(icon, "\uf111");
            //painter->drawImage(icon, QImage("/home/fisher/Pictures/images (1).jpeg"));
        }
    }
}

void SideBarDelegate::adjustDefaultTextColors(const QStyleOptionViewItem &option, QPainter &painter)  const
{
    if(option.state & QStyle::State_MouseOver) {
        painter.setPen(QColor(255, 255, 255));
    } else {
        painter.setPen(QColor(138, 164, 175));
    }
}

sidebarstyle.cpp sidebarstyle.cpp

#include "sidebarstyle.h"
#include <QStyleFactory>
#include <QStyleOption>
#include <QColor>

SideBarStyle::SideBarStyle()
    : QProxyStyle(QStyleFactory::create("linux"))
{
}

void SideBarStyle::drawPrimitive(PrimitiveElement element,
                                 const QStyleOption *option,
                                 QPainter *painter,
                                 const QWidget *widget) const
{
    if(element & PE_IndicatorBranch) {
        return;
    }
//    if(option->state & QStyle::State_HasFocus){
//        QStyleOptionViewItem myViewItemOption;
//        const QStyleOptionViewItem *viewItemOption =
//                qstyleoption_cast<const QStyleOptionViewItem *>(option);
//        if (viewItemOption) {
//            myViewItemOption = *viewItemOption;
//            myViewItemOption.palette.setBrush(QPalette::Highlight, QColor(30, 40, 44));
//            myViewItemOption.palette.setBrush(QPalette::HighlightedText, Qt::white);
//        }
//        QProxyStyle::drawPrimitive(element, &myViewItemOption, painter, widget);
//        return;
//    }
    QProxyStyle::drawPrimitive(element, option, painter, widget);

}

//void SideBarStyle::drawControl(ControlElement element,
//                               const QStyleOption *option,
//                               QPainter *painter,
//                               const QWidget *widget) const
//{
////    if(option->state & QStyle::State_HasFocus){
////        QStyleOptionViewItem myViewItemOption;
////        const QStyleOptionViewItem *viewItemOption =
////                qstyleoption_cast<const QStyleOptionViewItem *>(option);
////        if (viewItemOption) {
////            myViewItemOption = *viewItemOption;
////            myViewItemOption.palette.setBrush(QPalette::Highlight, QColor(30, 40, 44));
////            myViewItemOption.palette.setBrush(QPalette::HighlightedText, Qt::white);

////        }
////        QProxyStyle::drawControl(element, &myViewItemOption, painter, widget);
////        return;
////    }
//    QProxyStyle::drawControl(element, option, painter, widget);
//}

current picture当前图片

Also I borrowed some help from @eyllanesc answer to this question: How to remove QTreeView indentation我还从@eyllanesc 对这个问题的回答中借用了一些帮助: How to remove QTreeView indentation

You can try QWidget::setLayoutDirection你可以试试QWidget::setLayoutDirection

auto view = new QTreeView();
view->setLayoutDirection(Qt::RightToLeft);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM