c++qtqt5qitemdelegate

How to make a custom QItemDelegate for a particular row in a QTreeView?


How to make a custom QItemDelegate like on the attached picture. This is a QTreeView. The last element I want to customize and add a QItemDelegate enter image description here

For now I have only green separator line and would like to add a QCheckBox below the separator. How to implement this type of behavior?

void SeparatorItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    if (index.data(Qt::UserRole + 1).toString() == tr("Unsorted"))
    {
        QPen pen(Qt::green, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
        painter->setPen(pen);
        painter->drawLine(option.rect.left(), option.rect.center().y(), option.rect.right(), option.rect.center().y());
    }
    else
    {
        QItemDelegate::paint(painter, option, index);
    }
}

QSize SeparatorItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    if (index.data(Qt::UserRole + 1).toString() == tr("Unsorted"))
    {
        return QSize(200, 25);
    }
    return QItemDelegate::sizeHint(option, index);
}

void SeparatorItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    editor->setGeometry(option.rect);
}

THE PROBLEM IS: How to unite a SeparatorLine and a QChekBox in one custom item?


Solution

  • The idea of union in this case is to paint over as I show below:

    #include <QApplication>
    #include <QItemDelegate>
    #include <QPainter>
    #include <QStandardItemModel>
    #include <QTreeView>
    
    class SeparatorItemDelegate: public QItemDelegate
    {
    public:
    
        void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
        {
            QItemDelegate::paint(painter, option, index);
            if (index.data(Qt::UserRole + 1).toString() == tr("Unsorted"))
            {
    
                QPen pen(Qt::green, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
                painter->setPen(pen);
                QLine line(option.rect.topLeft(), option.rect.topRight());
                painter->drawLine(line);
            }
        }
    
        QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
        {
            if (index.data(Qt::UserRole + 1).toString() == tr("Unsorted"))
                return QSize(200, 25);
            return QItemDelegate::sizeHint(option, index);
        }
    };
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QTreeView w;
        SeparatorItemDelegate delegate;
        w.setItemDelegate(&delegate);
        QStandardItemModel model;
        for(const QString & root_name: {"Symbols", "Studies", "Drawings", "Unsorted"}){
            QStandardItem *root_item = new QStandardItem(root_name);
            root_item->setData(root_name);
            root_item->setCheckState(Qt::Checked);
            model.appendRow(root_item);
            for(int i=0; i < 3; i++){
                QStandardItem *child_item = new QStandardItem(root_name+QString::number(i));
                root_item->appendRow(child_item);
                child_item->setCheckState(Qt::Checked);
            }
        }
        w.setModel(&model);
        w.expandAll();
        w.resize(240, 480);
        w.show();
    
        return a.exec();
    }
    

    enter image description here