Search code examples
c++qtqt5qtreeviewqstandarditemmodel

Using QTreeView, how to highlight only specific row/colum with calling function?


I am using C++ Qt5. Currently I have a QStandardItemModel being displayed as a QTreeView with multiple rows and columns. I am aware of using setStyleSheet(), but the issue there is that every row and column that the mouse hovers is highlighted.

I would only like specific rows of the first column to be highlighted, and then have a function called for each cell highlighted that I would then use to manipulate my game.


Solution

  • The solution for a personalized painting is to use a custom delegate, and to indicate which item should change the color a role should be used, in the following code I show an example:

    #include <QApplication>
    #include <QStandardItemModel>
    #include <QStyledItemDelegate>
    #include <QTreeView>
    
    class StyledItemDelegate: public QStyledItemDelegate{
    public:
        using QStyledItemDelegate::QStyledItemDelegate;
    protected:
        void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const{
            QStyledItemDelegate::initStyleOption(option, index);
            if(index.data(Qt::UserRole +1).toBool())
                option->backgroundBrush = QBrush(Qt::red);
        }
    };
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QTreeView w;
        StyledItemDelegate delegate(&w);
        w.setItemDelegate(&delegate);
    
        QStandardItemModel model;
        model.setColumnCount(4);
        w.setModel(&model);
    
        for(int i=0; i<4; i++){
            auto it = new QStandardItem(QString::number(i));
            model.appendRow(it);
            for(int j=0; j<3; j++){
                it->appendRow(new QStandardItem(QString("%1-%2").arg(i).arg(j)));
            }
        }
        QObject::connect(&w, &QTreeView::clicked, [&](const QModelIndex & index){
            bool last_state = model.data(index, Qt::UserRole +1).toBool();
            model.setData(index, !last_state, Qt::UserRole +1);
        });
        w.expandAll();
        w.show();
        return a.exec();
    }