Search code examples
qtqt5qtreeviewqtwidgets

How to remove QTreeView indentation


I want to have a QTreeView without an indentation on the left side increasing at each nesting level. I tried setting QTreeView::setIndentation(0). It removes the indentations just as I want, however it also hides the tree arrows.


Default behavior:

  • With indentations ✗
  • With arrows ✔

Default behavior


After setIndentation(0):

  • Without indentations ✔
  • Without arrows ✗

After setIndentation(0)


Desired behavior:

  • Without indentations ✔
  • With arrows ✔

Desired behavior


So how can I achieve the result shown in the third example? Is there any standard way of doing it, or I will have to reimplement the QTreeView::paintEvent(), QTreeView::drawBranches(), etc.?


Solution

  • To solve the problem I used a delegate to translate the paint of the items, and paint the arrows.

    #include <QtWidgets>
    
    class BranchDelegate: public QStyledItemDelegate
    {
    public:
        using QStyledItemDelegate::QStyledItemDelegate;
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override{
            QStyleOptionViewItem opt(option);
            if(index.column() == 0)
                opt.rect.adjust(opt.rect.height(), 0, 0, 0);
            QStyledItemDelegate::paint(painter, opt, index);
            if(index.column() == 0){
                QStyleOptionViewItem branch;
                branch.rect = QRect(0, opt.rect.y(), opt.rect.height(), opt.rect.height());
                branch.state = option.state;
                const QWidget *widget = option.widget;
                QStyle *style = widget ? widget->style() : QApplication::style();
                style->drawPrimitive(QStyle::PE_IndicatorBranch, &branch, painter, widget);
            }
        }
    };
    
    class TreeView: public QTreeView
    {
    public:
        TreeView(QWidget *parent=nullptr):QTreeView(parent)
        {
            BranchDelegate *delegate = new BranchDelegate(this);
            setItemDelegate(delegate);
            setIndentation(0);
        }
    protected:
        void mousePressEvent(QMouseEvent *event) override{
            QModelIndex index = indexAt(event->pos());
            bool last_state = isExpanded(index);
            QTreeView::mousePressEvent(event);
            if(index.isValid() && last_state == isExpanded(index))
                setExpanded(index, !last_state);
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        TreeView w;
        QFileSystemModel model;
        model.setRootPath(QDir::rootPath());
        w.setModel(&model);
        w.setRootIndex(model.index(QDir::homePath()));
        /*for (int i = 1; i< model.columnCount() ; ++i) {
            w.hideColumn(i);
        }*/
        w.expandAll();
        w.resize(640, 480);
        w.show();
        return a.exec();
    }