From 483ae6c448ff95354c22e7d6e71117a9f9c40421 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Sun, 23 Oct 2022 21:15:01 +0200 Subject: [PATCH] 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 --- src/widgets/styles/qstylesheetstyle.cpp | 16 ++++++++++++---- .../stylesheet/qss/qtreeview/styledSelection.qss | 10 ++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 644f463b5d..518e452792 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4737,10 +4737,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op if (const QStyleOptionViewItem *vopt = qstyleoption_cast(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; diff --git a/tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss b/tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss new file mode 100644 index 0000000000..7d54a74fe5 --- /dev/null +++ b/tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss @@ -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 +}