StyleSheet: use item background rule when filling row backround

QTreeView draws the different sub-rects of an item's background over
multiple calls to drawPrimitive(PE_PanelItemViewRow). The item row is
not separately stylable, but the item might have a styled background
property. To get a consistent background, we must use the item's
background rule when filling the item's row background.

To fix that, delegate the filling of the branch background to
drawPrimitive(PE_PanelItemViewRow), and implement PE_PanelItemViewRow
handling to render the rule for the ViewItem pseudo element if there is
a background rule defined for it.

Add a baseline test stylesheet for this scenario. Note that the selection
in an item view is better styled via the selection-background-color
qss property.

Task-number: QTBUG-73251
Task-number: QTBUG-106227
Change-Id: I5d0c170f78009fe5015dd749975e6df27485b3b8
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 483ae6c448ff95354c22e7d6e71117a9f9c40421)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2022-10-23 21:15:01 +02:00 committed by Qt Cherry-pick Bot
parent eed3f07e02
commit 49392b41a4
2 changed files with 22 additions and 4 deletions

View File

@ -4734,10 +4734,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch); QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch);
if (subRule.hasDrawable()) { if (subRule.hasDrawable()) {
if ((vopt->state & QStyle::State_Selected) && vopt->showDecorationSelected) proxy()->drawPrimitive(PE_PanelItemViewRow, vopt, p, w);
p->fillRect(vopt->rect, vopt->palette.highlight());
else if (vopt->features & QStyleOptionViewItem::Alternate)
p->fillRect(vopt->rect, vopt->palette.alternateBase());
subRule.drawRule(p, opt->rect); subRule.drawRule(p, opt->rect);
} else { } else {
baseStyle()->drawPrimitive(pe, vopt, p, w); baseStyle()->drawPrimitive(pe, vopt, p, w);
@ -4805,6 +4802,17 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
pseudoElement = PseudoElement_DockWidgetSeparator; pseudoElement = PseudoElement_DockWidgetSeparator;
break; break;
case PE_PanelItemViewRow:
// For compatibility reasons, QTreeView draws different parts of
// the background of an item row separately, before calling the
// delegate to draw the item. The row background of an item is
// however not separately styleable through a style sheet, but
// only indirectly through the background of the item. To get the
// same background for all parts drawn by QTreeView, we have to
// use the background rule for the item here.
if (renderRule(w, opt, PseudoElement_ViewItem).hasBackground())
pseudoElement = PseudoElement_ViewItem;
break;
case PE_PanelItemViewItem: case PE_PanelItemViewItem:
pseudoElement = PseudoElement_ViewItem; pseudoElement = PseudoElement_ViewItem;
break; break;

View File

@ -0,0 +1,10 @@
QTreeView {
alternate-background-color: yellow;
show-decoration-selected: 1;
}
QTreeView::item:selected:active {
background: qlineargradient(x1:0, y1:0 x2: 0, y2: 1, stop: 0 #fea1f1 stop: 1 #567dbc)
}
QTreeView::branch {
border: 2px
}