Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Background color change not taking effect in QTreeView with stylesheet



  • Hello,
    I have a QTreeView to which I am applying the following stylesheet:

    const QString treeViewStyleSheet =
        "   QTreeView "
        "   {"
        "       alternate-background-color: #90CAF9;"
        "       background-color: #BBDEFB;"
        "   }"
        "   QTreeView "
        "   {"
        "       show-decoration-selected: 0;"
        "   }"
        "   QTreeView::item:selected {"
        "       border: 1px solid #567dbc;"
        "   }"
        "   QTreeView::item:selected:active{"
        "       background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, "
        "           stop: 0 #6ea1f1, stop: 1 #567dbc);"
        "   }"
        "   QTreeView::item:selected:!active {"
        "       background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, "
        "           stop: 0 #6b9be8, stop: 1 #577fbf);"
        "   }"
        "  QTreeView::branch:has-siblings:adjoins-item "
        "   {"
        "       border-image: url(:/branch-more.png) 0;"
        "   }"
        "   QTreeView::branch:!has-children:!has-siblings:adjoins-item "
        "   {"
        "       border-image: url(:/branch-end.png) 0;"
        "   }"
        "  QTreeView::branch:has-children:!has-siblings:closed, "
        "  QTreeView::branch:closed:has-children:has-siblings "
        "   {"
        "       border-image: none;"
        "       image: url(:/branch-closed.png);"
        "   }"
        "   QTreeView::branch:open:has-children:!has-siblings, "
        "   QTreeView::branch:open:has-children:has-siblings  "
        "   {"
        "       border-image: none;"
        "       image: url(:/branch-open.png);"
        "   }";
        this->setStyleSheet(treeViewStyleSheet);
    

    Then in the "::data(const QModelIndex &index, int role) const" method of the Model,

    if(role == Qt::BackgroundRole)
      {
    ...return green color
    }
    

    BUT, the background color of the cell does not change.

    If I DON'T apply the stylesheet by commenting out "this->setStyleSheet(treeViewStyleSheet);" then the background color from the "data" method is applied and visible. I tried removing all the entries from the stylesheet and that didn't solve the problem. It is as if applying the stylesheet means, Qt:BackgroundRole will NOT take effect.

    Can somebody please give me a hint on what is happening and how I can solve this problem?

    Thanks.


  • Moderators

    @JohnGa said in Background color change not taking effect in QTreeView with stylesheet:

    Can somebody please give me a hint on what is happening and how I can solve this problem?

    I've been hit by this in the past. The only solution I've found was to use setStyleSheet manually in delegates which needed a different colour. You can control the delegates for example by subclassing and using QStyledItemDelegate.



  • @JohnGa
    Basically as @sierdzio says: if you use a stylesheet rule for an attribute it overrides whatever you try to via style (like in your data() method). Sad but true.



  • Looks like this behavior is true only for the QTreeView. I have a QTableView, where I do the exact same thing: setAlternatingColors(true), setStyleSheet, and then specify background colors in the model data method for Qt::Background role. The new colors from the model data method are painted.



  • @JohnGa
    I'm surprised. What is it you specify for the stylesheet for this?



  • For the QTableView

        this->setAlternatingRowColors(true);
        this->setStyleSheet("alternate-background-color: #b8d1f3;background-color: #dae5f4;");
    

    Then in the data() method of the model, based on column number I return a different color. This works perfectly well. The color specified in the data() method is applied to the cells. Any cell background not changed by the data() method, shows the colors specified by the stylesheet.

    There is one difference between the QTableView and the QTreeView in my code: the QTableView cell colors are changed after setData() methods are called. Whereas in the QTreeView usage, I am not calling setData. So this must be the difference. Let my try by calling setData in the QTreeView....



  • If only the Qt classes were available to step into in QtCreator, these problems would NOT be so difficult to understand/resolve. I get only disassembled code, even though the paths are set correctly to the Qt source code. I am on Windows (my understanding is that the dev env is a lot better/faster on Linux/Mac...oh well). In any case, here is how I solved my problem.

    Firstly, the color returned by the Qt::BackgroundRole in the data() method of the model is queried during the painting but not used as the background color.
    When a QStyledItemDelegate is used, the paint() method calls initStyleMethod() which also calls the data() method of the model with Qt::BackgroundRole. But the color returned by the model is not used to paint the background.

    The only way, I could make this work is to do this in the paint() method of the QStyledItemDelegate:

    QColor background = QColor(128, 128, 128);
    painter->fillRect(qStyleOptionViewItem.rect, background);
    

    To make the above snippet flexible one could call the model and get the background color. I just chose to hardcode it, because the delegate is already set on a specific column. Wish I could have developed a clear understanding as to why the framework behaves the way it does....

    Thanks to @sierdzio and @JonB who rightfully pointed me in the right direction.



  • Hi, if you are using MSVC kit, you can step into the Qt source code if only you set the source path mapping and CDB symbol paths.
    But MingW kit seems not so easy, GDB doesn't functioning well in my Windows.


  • Moderators

    @JohnGa said in Background color change not taking effect in QTreeView with stylesheet:

    I am on Windows (my understanding is that the dev env is a lot better/faster on Linux/Mac...oh well)

    Yup, debugging on Linux works great. And compilation works much faster, too.



  • @sierdzio How about Mac? Is it comparable to Linux for Qt development?


  • Moderators

    @JohnGa said in Background color change not taking effect in QTreeView with stylesheet:

    @sierdzio How about Mac? Is it comparable to Linux for Qt development?

    I'm not a regular mac user so I can't answer this very well. There is some setup hassle (installing Xcode etc.), the CLI is bad (mac use some super old bash, old git version, old everything - at least used to, I've heard it's slowly changing), I also dislike they keyboard and shortcuts there. That's something to get used to, though. Other than that it works pretty well, at least up to a time when Apple decides to change the compiler again or force a new architecture and suddenly everything stops working :D


  • Lifetime Qt Champion

    Hi,

    Once you have Xcode installed, you can use macports or homebrew to install additional tools (or more recent versions of bash ;-))

    Then you pretty much get the same feeling as on Linux. You have to change Ctrl for Cmd when you are outside of a terminal and then you should feel at home.


Log in to reply