Style hover and selected colors for arbitrarely chosen QTreeWidgetItems

1.8k views Asked by At

I have a QTreeWidget and I have a stylesheet applied to it. I would like some of the QTreeWidgetItems to have different hover and selected colors than the rest of the styesheet styled items. I colored the normal state with setData(columnNumber, Qt::ForegroundRole, colorName) but I can't change their colors for hover and selected states.

Does anyone know if it is possible to achieve this in Qt in some way?

Thanks!

1

There are 1 answers

0
Jablonski On BEST ANSWER

AFAIK stylesheet is not a panacea for everything. You want very specific thing so you should look deeper and use something more powerful. I suggest you to use delegate. You didn't provide specification, so I provide main idea. In QStyledItemDelegate subclass reimplement paint. For example:

void ItemDelegatePaint::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QString txt = index.model()->data( index, Qt::DisplayRole ).toString();

    if( option.state & QStyle::State_Selected )//it is your selection
    {
        if(index.row()%2)//here we try to see is it a specific item
            painter->fillRect( option.rect,Qt::green );//special color
        else
            painter->fillRect( option.rect, option.palette.highlight() );
        painter->drawText(option.rect,txt);//text of item
    } else
    if(option.state & QStyle::State_MouseOver)//it is your hover
    {
        if(index.row()%2)
            painter->fillRect( option.rect,Qt::yellow );
        else
            painter->fillRect( option.rect, Qt::transparent );
        painter->drawText(option.rect,txt);
    }
    else
    {
        QStyledItemDelegate::paint(painter,option,index);//standard process
    }

}

Here I set some specific properties to every second item, but you can use another specific items.

QTreeWidget Inherits QTreeView so use:

ui->treeWidget->setItemDelegate(new ItemDelegatePaint);

It seems that your widget is complex, so I hope that you understand main idea and you will be able to write delegate which will be absolutely suitable for you. If you didn't work with delegates before, then check examples, it is not very complex.

http://qt-project.org/doc/qt-4.8/itemviews-stardelegate-stardelegate-h.html

http://qt-project.org/doc/qt-4.8/itemviews-stardelegate-stardelegate-cpp.html

In my answer I used next delegate:

#ifndef ITEMDELEGATEPAINT_H
#define ITEMDELEGATEPAINT_H

#include <QStyledItemDelegate>
class ItemDelegatePaint : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit ItemDelegatePaint(QObject *parent = 0);
    ItemDelegatePaint(const QString &txt, QObject *parent = 0);


protected:
    void paint( QPainter *painter,
                const QStyleOptionViewItem &option,
                const QModelIndex &index ) const;
    QSize sizeHint( const QStyleOptionViewItem &option,
                    const QModelIndex &index ) const;
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget * editor, const QModelIndex & index) const;
    void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
    void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const;

signals:

public slots:

};

#endif // ITEMDELEGATEPAINT_H

There are many methods here but paint is most important for you.