Add attribute to indicate a widget was the target of a style sheet

Qt already has the widget attribute WA_StyleSheet to which indicates that
a widget was subject to a style sheet, but it doesn't indicate that the
widget was actually affected by the style sheet. For example, an application
style sheet will set the WA_StyleSheet attribute on all widgets, even if it
only targets QPushButtons. The WA_StyleSheetTarget new attribute pairs with
WA_StyleSheet to give this extra information.

[ChangeLog][QtWidgets] Added the Qt::WA_StyleSheetTarget attribute to
indicate that a widget was affected by a style sheet.

Change-Id: I7cca18ddec8fbb69f294ae2ef990672a5f4f1d83
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
Reviewed-by: Sérgio Martins <sergio.martins@kdab.com>
This commit is contained in:
Aaron Kennedy 2018-05-09 23:04:00 +10:00
parent 91f12fe62b
commit c83ea33ceb
4 changed files with 84 additions and 1 deletions

View File

@ -486,6 +486,8 @@ public:
WA_ContentsMarginsRespectsSafeArea = 130,
WA_StyleSheetTarget = 131,
// Add new attributes before this line
WA_AttributeCount
};

View File

@ -1153,7 +1153,12 @@
the widget's author.
\value WA_StyleSheet Indicates that the widget is styled using a
\l{Qt Style Sheets}{style sheet}.
\l{Qt Style Sheets}{style sheet}. WA_StyleSheet is set whenever a widget
is subject to a style sheet, even if the style sheet did not affect the
widget appearance.
\value WA_StyleSheetTarget Indicates that the widget appearance was modified
by a \l{Qt Style Sheets}{style sheet}. WA_StyleSheet will also be set.
\value WA_TabletTracking Indicates that the widget has tablet
tracking enabled. See QWidget::tabletTracking.

View File

@ -530,6 +530,8 @@ public:
const QStyleSheetGeometryData *geometry() const { return geo; }
const QStyleSheetPositionData *position() const { return p; }
bool hasModification() const;
bool hasPalette() const { return pal != 0; }
bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); }
bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern
@ -1444,6 +1446,21 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
}
bool QRenderRule::hasModification() const
{
return hasPalette() ||
hasBackground() ||
hasGradientBackground() ||
!hasNativeBorder() ||
!hasNativeOutline() ||
hasBox() ||
hasPosition() ||
hasGeometry() ||
hasImage() ||
hasFont ||
!styleHints.isEmpty();
}
///////////////////////////////////////////////////////////////////////////////
// Style rules
#define OBJECT_PTR(x) (static_cast<QObject *>(x.ptr))
@ -2823,6 +2840,9 @@ void QStyleSheetStyle::polish(QWidget *w)
#endif
QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
w->setAttribute(Qt::WA_StyleSheetTarget, rule.hasModification());
if (rule.hasDrawable() || rule.hasBox()) {
if (w->metaObject() == &QWidget::staticMetaObject
#if QT_CONFIG(itemviews)
@ -2909,6 +2929,7 @@ void QStyleSheetStyle::unpolish(QWidget *w)
w->setProperty("_q_stylesheet_minh", QVariant());
w->setProperty("_q_stylesheet_maxw", QVariant());
w->setProperty("_q_stylesheet_maxh", QVariant());
w->setAttribute(Qt::WA_StyleSheetTarget, false);
w->setAttribute(Qt::WA_StyleSheet, false);
QObject::disconnect(w, 0, this, 0);
#if QT_CONFIG(scrollarea)

View File

@ -98,6 +98,8 @@ private slots:
void widgetStyle();
void appStyle();
void QTBUG11658_cachecrash();
void styleSheetTargetAttribute();
private:
QColor COLOR(const QWidget& w) {
w.ensurePolished();
@ -1999,6 +2001,59 @@ void tst_QStyleSheetStyle::widgetStylePropagation()
QCOMPARE(COLOR(childLabel), childExpectedColor);
}
void tst_QStyleSheetStyle::styleSheetTargetAttribute()
{
QGroupBox gb;
QLabel lb(&gb);
QPushButton pb(&lb);
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
qApp->setStyleSheet("QPushButton { background-color: blue; }");
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), true);
qApp->setStyleSheet("QGroupBox { background-color: blue; }");
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), true);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
qApp->setStyleSheet("QGroupBox * { background-color: blue; }");
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), true);
qApp->setStyleSheet("* { background-color: blue; }");
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), true);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), true);
qApp->setStyleSheet("QLabel { font-size: 32pt; }");
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
qApp->setStyleSheet("");
gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
}
QTEST_MAIN(tst_QStyleSheetStyle)
#include "tst_qstylesheetstyle.moc"