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
Pick-to: 6.4 6.2
Change-Id: I5d0c170f78009fe5015dd749975e6df27485b3b8
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Volker Hilsheimer 2022-10-23 21:15:01 +02:00
parent 6f9d31be49
commit 483ae6c448
2 changed files with 22 additions and 4 deletions

View File

@ -4737,10 +4737,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch);
if (subRule.hasDrawable()) {
if ((vopt->state & QStyle::State_Selected) && vopt->showDecorationSelected)
p->fillRect(vopt->rect, vopt->palette.highlight());
else if (vopt->features & QStyleOptionViewItem::Alternate)
p->fillRect(vopt->rect, vopt->palette.alternateBase());
proxy()->drawPrimitive(PE_PanelItemViewRow, vopt, p, w);
subRule.drawRule(p, opt->rect);
} else {
baseStyle()->drawPrimitive(pe, vopt, p, w);
@ -4808,6 +4805,17 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
pseudoElement = PseudoElement_DockWidgetSeparator;
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:
pseudoElement = PseudoElement_ViewItem;
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
}