How to use style sheet in qt to not to change row color on selection.
-
I have a QTreeWidget with some rows and columns. Rows have specific color.
But on mouse click ( selection ) it is changing background color (which I do not want). ( Please look below screen shot)
( I have clicked on the middle row and it is changing it's background color )
So I tried following style sheet ( but it is not working )
"QTreeWidget::item:selected:active { "border: 1px solid red;" "}";
So What am I looking for ?
- On selection of row, it should not change its background color, but I should get some feel of selection (like border should get darken or border color should change etc )
How to do that ? Can anyone help me in style sheet ?
-
@tushu said in How to use style sheet in qt to not to change row color on selection.:
QTreeWidget
Try changing this to QTreeView like in the help is suggested:
"```
QTreeView {
show-decoration-selected: 1;
}QTreeView::item {
border: 1px solid #d9d9d9;
border-top-color: transparent;
border-bottom-color: transparent;
}QTreeView::item:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
border: 1px solid #bfcde4;
}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);
} -
@tushu said in How to use style sheet in qt to not to change row color on selection.:
QTreeWidget
Try changing this to QTreeView like in the help is suggested:
"```
QTreeView {
show-decoration-selected: 1;
}QTreeView::item {
border: 1px solid #d9d9d9;
border-top-color: transparent;
border-bottom-color: transparent;
}QTreeView::item:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
border: 1px solid #bfcde4;
}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);
} -
Ok! You are right :)
I have searched a bit and in src of Qt6.4.0 in: qtbase/src/widgets/styles/qcommonstyle.cpp at line: 657
you see how the default item is drawn, therefore if you do something like this:QPalette pal { ui->treeView1->palette() }; pal.setBrush(QPalette::Active, QPalette::Highlight, Qt::red); ui->treeView1->setPalette(pal);
for me with this I have a red background and not blue. :)
-
QTreeView::item:selected{ color: palette(text); /* use default text color, you can change to other colors you want */ background-color: palette(base); /* use default background color, you can change to other colors you want*/ border: 1px solid red;/* set border properties to what you want */ }
Note that will also override the colors of hovered rows when selected, if you want to set them then add something like
QTreeView::item:selected:hover{ background-color: lightblue; }
-
QTreeView::item:selected{ color: palette(text); /* use default text color, you can change to other colors you want */ background-color: palette(base); /* use default background color, you can change to other colors you want*/ border: 1px solid red;/* set border properties to what you want */ }
Note that will also override the colors of hovered rows when selected, if you want to set them then add something like
QTreeView::item:selected:hover{ background-color: lightblue; }
-
@tushu
palette(text)
means usingQPalette::Text
.
See https://doc.qt.io/qt-5/stylesheet-reference.html#brush and https://doc.qt.io/qt-5/stylesheet-reference.html#paletterole.
Because I don't know your full code of stylesheet or how you set colors, this just means to use the default color in normal state.
Sure you can use "color: black" and "background-color: green" like in usual stylesheet color properties.
I also notice that you still get the left empty part of blue highlighted background, this can also be changed byQTreeView::branch:selected{ background-color: some-color; }
or just
QTreeView { show-decoration-selected: 0; }
-
@tushu
palette(text)
means usingQPalette::Text
.
See https://doc.qt.io/qt-5/stylesheet-reference.html#brush and https://doc.qt.io/qt-5/stylesheet-reference.html#paletterole.
Because I don't know your full code of stylesheet or how you set colors, this just means to use the default color in normal state.
Sure you can use "color: black" and "background-color: green" like in usual stylesheet color properties.
I also notice that you still get the left empty part of blue highlighted background, this can also be changed byQTreeView::branch:selected{ background-color: some-color; }
or just
QTreeView { show-decoration-selected: 0; }
@Bonnie I tried what you said just and it improved my output.
Currently it is looking like this :by your current suggestion that left side blue patch gone. But still I am missing my original colors. Now instead of white strip I want to my original color
And my current style sheet is :
QString GetTreeStyle() { QString style = "QTreeView { "show-decoration-selected: 0; "}" "QTreeView::item:selected{ "color: palette(text);" "background-color: palette(base);" "border: 1px solid red;" "}"; return style; }
-
@Bonnie I tried what you said just and it improved my output.
Currently it is looking like this :by your current suggestion that left side blue patch gone. But still I am missing my original colors. Now instead of white strip I want to my original color
And my current style sheet is :
QString GetTreeStyle() { QString style = "QTreeView { "show-decoration-selected: 0; "}" "QTreeView::item:selected{ "color: palette(text);" "background-color: palette(base);" "border: 1px solid red;" "}"; return style; }
-
@tushu Sadly stylesheet can't get the color set by
setBackgroundColor
.
In this situation I would suggest using a custom item delegate.-
remove stylesheet contents but keep "show-decoration-selected: 0"
-
subclass
QStyledItemDelegate
and reimplementinitStyleOption
void CustomItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const { option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows QStyledItemDelegate::initStyleOption(option, index); }
- create a CustomItemDelegate object and set it to the view by
setItemDelegate
But by this method you cannot set border for a selected row anymore.
By default there's a focus frame for the focused item, you may callsetAllColumnsShowFocus(true)
to make it cover the whole row to show the "selected row". -
-
@tushu Sadly stylesheet can't get the color set by
setBackgroundColor
.
In this situation I would suggest using a custom item delegate.-
remove stylesheet contents but keep "show-decoration-selected: 0"
-
subclass
QStyledItemDelegate
and reimplementinitStyleOption
void CustomItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const { option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows QStyledItemDelegate::initStyleOption(option, index); }
- create a CustomItemDelegate object and set it to the view by
setItemDelegate
But by this method you cannot set border for a selected row anymore.
By default there's a focus frame for the focused item, you may callsetAllColumnsShowFocus(true)
to make it cover the whole row to show the "selected row".@Bonnie Perfect solution. It worked perfectly.
But I got suggestion over the output.
Current output is :Clicked row ( add_7 ) is originally without color ( white ) . But after click, it slightly becoming bluish. Can we remove that light blue color ?
2nd row is clicked.
But when I click on a coloured row, it looks fine.
Is there any way to remove that light blue color when I click on non coloured row ?
And many thanks for your efforts and perfect Solution.
-
-
@Bonnie Perfect solution. It worked perfectly.
But I got suggestion over the output.
Current output is :Clicked row ( add_7 ) is originally without color ( white ) . But after click, it slightly becoming bluish. Can we remove that light blue color ?
2nd row is clicked.
But when I click on a coloured row, it looks fine.
Is there any way to remove that light blue color when I click on non coloured row ?
And many thanks for your efforts and perfect Solution.
One more favor.
You have suggested following code. BUt I am not understanding what are you doing exactly.void CustomItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const { option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows QStyledItemDelegate::initStyleOption(option, index); }
In 2nd line , you are calling the initStyleOption() again.
But what are you doing in 1st line ?
Can you explain that ? -
@Bonnie Perfect solution. It worked perfectly.
But I got suggestion over the output.
Current output is :Clicked row ( add_7 ) is originally without color ( white ) . But after click, it slightly becoming bluish. Can we remove that light blue color ?
2nd row is clicked.
But when I click on a coloured row, it looks fine.
Is there any way to remove that light blue color when I click on non coloured row ?
And many thanks for your efforts and perfect Solution.
-
One more favor.
You have suggested following code. BUt I am not understanding what are you doing exactly.void CustomItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const { option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows QStyledItemDelegate::initStyleOption(option, index); }
In 2nd line , you are calling the initStyleOption() again.
But what are you doing in 1st line ?
Can you explain that ?@tushu said in How to use style sheet in qt to not to change row color on selection.:
But what are you doing in 1st line ?
option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows
Switches off/clears the
QStyle::State_Selected
bit inoption->state
, leaving all other bits untouched. -
One more favor.
You have suggested following code. BUt I am not understanding what are you doing exactly.void CustomItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const { option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows QStyledItemDelegate::initStyleOption(option, index); }
In 2nd line , you are calling the initStyleOption() again.
But what are you doing in 1st line ?
Can you explain that ?@tushu said in How to use style sheet in qt to not to change row color on selection.:
But what are you doing in 1st line ?
-
@tushu light blue color may be caused by focus. Try to set no focus to each item to see if the color is gone.
@JoeCFD
To get focus I have added following line.setAllColumnsShowFocus(true);
If I remove that line, then by default focus will be given to a particular cell ( column) where I have clicked with same light blue colour.
Moreover, If I remove it completely, then I will miss a feel of row selection. I want row selection feeling also.
-
@tushu said in How to use style sheet in qt to not to change row color on selection.:
But what are you doing in 1st line ?
option->state &= ~QStyle::State_Selected; //make sure no item is flaged as selected when drawing rows
Switches off/clears the
QStyle::State_Selected
bit inoption->state
, leaving all other bits untouched. -
@JonB Thanks for your help.
Sorry but still I am confused.
I did not get the purpose behind this bits clearing. -
@JonB
What I understood : When I will click on any row, it will get selected and this method will get invoke. And then , thorugh this method , I will deselect my current selection by clearing bits and calling that method again. So in the end, there will not be any selection. So no dark blue default selection of row by Qt.Sorry if my understanding is wrong.