Styling branches in QTreeWidget per item


  • Moderators

    Hi,

    I'm styling a QTreeWidget by coloring its rows like so:
    treeview

    This is the code I used:

        QTreeWidgetItem * item, * child;
        QStringList texts;
        texts << "Label" << "value";
    
        item = new QTreeWidgetItem(treeWidget, texts);
        child = new QTreeWidgetItem(item, texts);
        item->setBackgroundColor(0,Qt::red);
        child->setBackgroundColor(0,Qt::red);
        item->setBackgroundColor(1,Qt::cyan);
        child->setBackgroundColor(1,Qt::cyan);
    
        item = new QTreeWidgetItem(treeWidget, texts);
        child = new QTreeWidgetItem(item, texts);
        item->setBackgroundColor(0,Qt::green);
        child->setBackgroundColor(0,Qt::green);
        item->setBackgroundColor(1,Qt::cyan);
        child->setBackgroundColor(1,Qt::cyan);
    

    Nothing special, but I'd like to make branches the same color as labels, so that the whole row is colored. Is there any way to do that per item?

    The only way I know to style branches is to use QTreeView::branch css style, but that applies one style to all of them, and I need something per-item based.
    Item delegate doesn't draw branches from what I know, does it?

    I'd like to avoid reimplementing whole QTreeWidget drawing if possible. Any ideas?



  • Just some quick brainstorming

    • subclass [[Doc:QStyledItemDelegate]]
    • reimplement paint, set the background in the option and call the base class' implementation with the manipulated data

  • Moderators

    Thanks Volker,

    The delegate by default does not draw the branch part of the row, only the column data part (red, green and cyan parts on the pic), so changing bg color in paint options isn't enough (btw. bg color is for some strange reason set to RGBA {1,1,1,0} there so the way to get it is from index bg color role).

    Anyway Your suggestion was close enough to lead me to this solution:

    class MyDelegate: public QStyledItemDelegate
    {
    public:
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            QStyledItemDelegate::paint(painter, option, index);
    
            if(index.column() == 0)
            {
                QRect branchRect(0, option.rect.top(), option.rect.left(), option.rect.height());
                painter->setCompositionMode(QPainter::CompositionMode_Multiply);
                painter->fillRect(branchRect, index.data(Qt::BackgroundColorRole).value<QColor>());
                painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
            }
        }
    };
    

    As I imagine this is not 100% correct. Overpainting the branch area in items paint event will not work if on some platforms branches are drawn AFTER the items themselves, but I assume this won't happen in any sane implementation.
    Of course, as Everett McGill said "assumption is the mother of all f**kups", but hey, it works on my machine :)

    Thanks a bunch again.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.