Important: Please read the Qt Code of Conduct -

How can I disable highlight of selected items, but still leave selection mode enabled in a QTreeView?

  • Re: Changing QPalette::Highlight has no effect for QTreeView.

    I reference the above question, because the OP clarifies, later in the thread, that he wants what I want. This question was never resolved.

    I want to stop the highlight color from appearing on selected items in the QTreeView. The default color is a dark blue. I do NOT want to change the selection color; I want it to quit changing the color. I am using a programmatic method of changing the background colors which relies on a very specific algorithm. I cannot have the colors being changed by merely being selected, not even temporarily while the user selects them. They must react to my programmatic color changes immediately, so I need this selection highlighting to completely stop, BUT I must still have the ability to set the selection mode to:

    Note: I have already tried, among many things, overriding the paint() function in a QStyledItemDelegate. It does not appear to matter what color I choose there: the selection highlight overrides it.

    The closest I have come is when, also in the paint() function, I add this:
    QStyleOptionViewItem *myOption = new QStyleOptionViewItem(option);
    myOption->showDecorationSelected = false;
    QStyledItemDelegate::paint( painter, *myOption, index );

    However, that only limits the highlight "decoration" blue color to the parts of the item with text. At least I can see the background color that I want in that scenario, but it looks quite sloppy. I need the highlight GONE completely. I have been working on this literally for weeks. Any help is greatly appreciated.

    Please advise. Thank you!

    See below a screenshot of a mock up I created. Notice the blue highlight on the left side of the selected items. This is because of the "showDecorationSelected = false" mentioned above. As you can see, the background color is visible, but only where there is no text. I want this blue to go away completely, not just retreat to the left.

  • @MattCleere But without the highlight color, how can you know which rows are selected?
    I can simply disable the highlight color by

    QStyleOptionViewItem myOption = QStyleOptionViewItem(option);
    myOption.state &= ~QStyle::State_Selected;
    QStyledItemDelegate::paint( painter, myOption, index );

    But I'm not sure whether this is what you want.

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    If you are only interested in the text part then paint only the text and not the highlight.

  • Let me be sure, when an item is selected, you want it not be highlighted when hovered, just keep the selected color? While other unselected ones still be highlighted when hovered?
    In that case try

    if(myOption->state & QStyle::State_Selected)
        myOption->state &= ~QStyle::State_MouseOver;

    P.S don't forget to delete myOption, or you shouldn't use new.

  • @Bonnie Thanks for your response. I am not concerned with the hover functionality. Selection is my concern. Whenever an item is left-clicked, or ctrl - clicked, or shift - clicked, it becomes "selected". This both places the item on a list of selected items, which may be managed through the selection model, AND it causes that delegate/cell/item to be put into the "highlighted" state. This highlighted state causes that item to be colored blue with white text by default. I am fully aware that that both the highlight color and highlighted text color may be changed via style sheets, or other internal means. This is not my concern either. What I want is for the highlighting to STOP. It is fine if the items change color when hovered, but NOT when they are selected. This is very important, because my algorithm will give selected items very specific colors based on relationships that need not be described here, but that NEED to be seen by the user as they select. The user will be quite annoyed that they cannot see these colors while the items are selected, just because this blue color insists on taking over all the time. I hope that clarifies it.

  • @MattCleere But without the highlight color, how can you know which rows are selected?
    I can simply disable the highlight color by

    QStyleOptionViewItem myOption = QStyleOptionViewItem(option);
    myOption.state &= ~QStyle::State_Selected;
    QStyledItemDelegate::paint( painter, myOption, index );

    But I'm not sure whether this is what you want.

  • Thanks again for your response Bonnie.

    I'm going to call this the "correct answer". It's not perfect, but it definitely helps! Thanks a ton Bonnie!

    You can see in the image that their is still a highlight to the left side of the item, but no longer ON the item. This is good.

    Since you answered my question first and then asked me why, I will tell you.
    The red color is my own highlight that I am adding through an algorithm. This will change to many potential colors determined by properties in the data, combined with being "selected". Anything that is selected will show it, but some will be red, some will be purple, etc. They will actually be matching the color of objects in a Qt3D space. It's quite complicated, and I cannot explain here, but rest assured, I will be representing their "selectedness" just with my OWN colors. So I do not need the built-in highlighting (blue in this case) at all. However, we can live with it being along the left only, for now.

    I apologize for the late reply, but this is a project that I do not have a ton of time for lately. And again, thank you for simply answering the question, instead of analyzing the validity of my choices.

    {Pertaining to forum questions, in general, because Bonnie is not guilty of what I describe below, rather she gave a perfect example of a very helpful answer, sprinkled with a bit of curiosity. I see this everywhere and it is obnoxious and eternally unhelpful...}
    I can't stand it when people ask the OP "why?" without answering the question. They are not so much trying to learn why as they are arguing with the OP and telling them that they are doing something wrong. I say, save the opinions for after you answer the question, because any and/or ALL of your assumptions may be completely unfounded, AND one's own lack of information about motivations has absolutely nothing to do with the validity of a particular choice in programming, especially when it is a stylistic choice. The worst is when people say, "don't do that, do this". So self righteous. It's like I asked you how to get to Dairy Queen and you say, "Don't go to Dairy Queen, go to Braum's! They are so much better." And I am forced to slow down and tell you, "Dude... my WIFE is at Dairy Queen, how do I get there!" Insufferable.

  • @Bonnie I tried your wonderfully simple solution on a QTableView instead of a QTreeView and sadly it didn't work. My use case requires selectable rows in order to initiate a drag copy to another window. The selection coloring at the start of the drag (the mouse click) is a visual annoyance that I wanted to turn off. I did develop a delegate that does work for a table view, however. It was a little tricky because 1) alternating rows can have different base colors and 2) my model might provide a text (foreground) color. That said, this delegate does work, using palette color manipulation:

        QStyleOptionViewItem local_option = option;
        QColor color_base = local_option.features.testFlag(QStyleOptionViewItem::Alternate)
                ? local_option.palette.color(QPalette::AlternateBase)
                : local_option.palette.color(QPalette::Base);
        QVariant color_text_v = index.model()->data(index, Qt::ForegroundRole);
        QColor color_text = color_text_v.isValid() ? color_text_v.value<QColor>()
                                                   : local_option.palette.color(QPalette::Text);
        // clobber the selection coloring with ordinary coloring
        local_option.palette.setColor(QPalette::Highlight, color_base);
        local_option.palette.setColor(QPalette::HighlightedText, color_text);
        QStyledItemDelegate::paint(painter, local_option, index) ;

Log in to reply