summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@intopalo.com>2015-06-28 21:31:30 +1000
committerSamuel Nevala <samuel.nevala@intopalo.com>2015-09-10 06:44:57 +0000
commit7293200ace12f4870b87bb6a1f5a22ef53bf52cd (patch)
treedd1e3dfc20cb5ed0822a2ead275e392d99bff1d8
parentaaab800e1651fc9f04d62a76eda9b8cafbbe14c0 (diff)
Add attribute to enable font and palette propagation in QSS.
By default when using Qt Style Sheets, a widget does not inherit its font and palette from its parent widget. With the Qt::AA_UseStyleSheetPropagationInWidgetStyles application attribute set, propagation when using Qt Style Sheets behaves like it does with regular QWidget::setPalette() and QWidget::setFont() calls. [ChangeLog][QtWidgets] Added the Qt::AA_UseStyleSheetPropagationInWidgetStyles attribute which enables font and palette propagation for Qt Style Sheets. Task-number: QTBUG-37580 Change-Id: I3038c13d61e32625a1a05291c5394eaefd376a68 Reviewed-by: Samuel Nevala <samuel.nevala@intopalo.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc7
-rw-r--r--src/widgets/doc/snippets/code/doc_src_stylesheet.cpp4
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc22
-rw-r--r--src/widgets/kernel/qwidget.cpp33
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp121
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h6
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp228
8 files changed, 373 insertions, 49 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index e62b658afc..056e519e56 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -498,6 +498,7 @@ public:
AA_ShareOpenGLContexts = 18,
AA_SetPalette = 19,
AA_NoHighDpiScaling = 20,
+ AA_UseStyleSheetPropagationInWidgetStyles = 21, // ### Qt 6: remove me
// Add new attributes before this line
AA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index c7effe0c0c..b7c6500831 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -213,6 +213,13 @@
so this does not guarantee that QPaintDevice::devicePixelRatio() will
be equal to 1. This value has been added in Qt 5.6.
+ \value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets
+ disable regular QWidget palette and font propagation. When this flag
+ is enabled, font and palette changes propagate as though the user had
+ manually called the corresponding QWidget methods. See
+ \l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance}
+ for more details. This value has been added in Qt 5.7.
+
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully
diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp b/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp
index a937498fe5..01f4c528a2 100644
--- a/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp
+++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp
@@ -138,3 +138,7 @@ emailEdit->setProperty("mandatoryField", true);
QSpinBox *ageSpinBox = new QSpinBox(this);
ageSpinBox->setProperty("mandatoryField", true);
//! [95]
+
+//! [96]
+qApp->setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
+//! [97]
diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
index fc3ac345a8..bea1a6e657 100644
--- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
@@ -492,9 +492,9 @@
\section1 Inheritance
In classic CSS, when font and color of an item is not explicitly set,
- it gets automatically inherited from the parent. When using Qt Style Sheets,
- a widget does \b{not} automatically inherit its font and color setting
- from its parent widget.
+ it gets automatically inherited from the parent. By default, when using
+ Qt Style Sheets, a widget does \b{not} automatically inherit its font
+ and color setting from its parent widget.
For example, consider a QPushButton inside a QGroupBox:
@@ -507,9 +507,23 @@
\snippet code/doc_src_stylesheet.cpp 25
- In contrast, setting a font and propagate using QWidget::setFont() and
+ In contrast, setting a font and palette using QWidget::setFont() and
QWidget::setPalette() propagates to child widgets.
+ If you would prefer that the font and palette propagate to child widgets,
+ you can set the Qt::AA_UseStyleSheetPropagationInWidgetStyles flag, like
+ this:
+
+ Usage:
+ \snippet code/doc_src_stylesheet.cpp 96
+
+ When the widget-style font and palette propagation is enabled, font and
+ palette changes made through Qt Style Sheets will behave as though the
+ user had manually called the corresponding QWidget::setPalette() and
+ QWidget::setFont() methods on all of the QWidgets targeted by the style
+ sheet. If this would have caused propagation in C++, it will cause
+ propagation in style sheets and visa versa.
+
\section1 Widgets Inside C++ Namespaces
The Type Selector can be used to style widgets of a particular type. For
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 1ebf782edf..66ded4cb5f 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1954,11 +1954,14 @@ void QWidgetPrivate::propagatePaletteChange()
}
int mask = data.pal.resolve() | inheritedPaletteResolveMask;
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
QEvent pc(QEvent::PaletteChange);
QApplication::sendEvent(q, &pc);
for (int i = 0; i < children.size(); ++i) {
QWidget *w = qobject_cast<QWidget*>(children.at(i));
- if (w && !w->testAttribute(Qt::WA_StyleSheet)
+ if (w && (!w->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
QWidgetPrivate *wd = w->d_func();
wd->inheritedPaletteResolveMask = mask;
@@ -4543,15 +4546,19 @@ void QWidget::setPalette(const QPalette &palette)
QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
{
Q_Q(const QWidget);
+
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
QPalette naturalPalette = QApplication::palette(q);
- if (!q->testAttribute(Qt::WA_StyleSheet)
+ if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
#ifndef QT_NO_GRAPHICSVIEW
|| (extra && extra->proxyWidget)
#endif //QT_NO_GRAPHICSVIEW
)) {
if (QWidget *p = q->parentWidget()) {
- if (!p->testAttribute(Qt::WA_StyleSheet)) {
+ if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
if (!naturalPalette.isCopyOf(QApplication::palette())) {
QPalette inheritedPalette = p->palette();
inheritedPalette.resolve(inheritedMask);
@@ -4687,15 +4694,19 @@ void QWidget::setFont(const QFont &font)
QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
{
Q_Q(const QWidget);
+
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
QFont naturalFont = QApplication::font(q);
- if (!q->testAttribute(Qt::WA_StyleSheet)
+ if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
#ifndef QT_NO_GRAPHICSVIEW
|| (extra && extra->proxyWidget)
#endif //QT_NO_GRAPHICSVIEW
)) {
if (QWidget *p = q->parentWidget()) {
- if (!p->testAttribute(Qt::WA_StyleSheet)) {
+ if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
if (!naturalFont.isCopyOf(QApplication::font())) {
QFont inheritedFont = p->font();
inheritedFont.resolve(inheritedMask);
@@ -4747,6 +4758,8 @@ void QWidgetPrivate::updateFont(const QFont &font)
#ifndef QT_NO_STYLE_STYLESHEET
const QStyleSheetStyle* cssStyle;
cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
#endif
data.fnt = QFont(font, q);
@@ -4771,7 +4784,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
if (w) {
if (0) {
#ifndef QT_NO_STYLE_STYLESHEET
- } else if (w->testAttribute(Qt::WA_StyleSheet)) {
+ } else if (!useStyleSheetPropagationInWidgetStyles && w->testAttribute(Qt::WA_StyleSheet)) {
// Style sheets follow a different font propagation scheme.
if (cssStyle)
cssStyle->updateStyleSheetFont(w);
@@ -4786,7 +4799,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
}
#ifndef QT_NO_STYLE_STYLESHEET
- if (cssStyle) {
+ if (!useStyleSheetPropagationInWidgetStyles && cssStyle) {
cssStyle->updateStyleSheetFont(q);
}
#endif
@@ -10442,7 +10455,11 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
d->reparentFocusWidgets(oldtlw);
setAttribute(Qt::WA_Resized, resized);
- if (!testAttribute(Qt::WA_StyleSheet)
+
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
+ if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet)
&& (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
d->resolveFont();
d->resolvePalette();
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 380b2b3939..c9440efc8c 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -2556,7 +2556,13 @@ void QStyleSheetStyle::setPalette(QWidget *w)
{ PseudoClass_Enabled, QPalette::Inactive }
};
- QPalette p = w->palette();
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
+ QPalette p;
+ if (!useStyleSheetPropagationInWidgetStyles)
+ p = w->palette();
+
QWidget *ew = embeddedWidget(w);
for (int i = 0; i < 3; i++) {
@@ -2573,32 +2579,84 @@ void QStyleSheetStyle::setPalette(QWidget *w)
rule.configurePalette(&p, map[i].group, ew, ew != w);
}
- styleSheetCaches->customPaletteWidgets.insert(w, w->palette());
- w->setPalette(p);
- if (ew != w)
- ew->setPalette(p);
+ if (!useStyleSheetPropagationInWidgetStyles || p.resolve() != 0) {
+ QPalette wp = w->palette();
+ styleSheetCaches->customPaletteWidgets.insert(w, qMakePair(wp, p.resolve()));
+
+ if (useStyleSheetPropagationInWidgetStyles) {
+ p = p.resolve(wp);
+ p.resolve(p.resolve() | wp.resolve());
+ }
+
+ w->setPalette(p);
+ if (ew != w)
+ ew->setPalette(p);
+ }
}
void QStyleSheetStyle::unsetPalette(QWidget *w)
{
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
if (styleSheetCaches->customPaletteWidgets.contains(w)) {
- QPalette p = styleSheetCaches->customPaletteWidgets.value(w);
- w->setPalette(p);
+ QPair<QPalette, uint> p = styleSheetCaches->customPaletteWidgets.value(w);
+ styleSheetCaches->customPaletteWidgets.remove(w);
+
+ QPalette original = p.first;
+
+ if (useStyleSheetPropagationInWidgetStyles) {
+ original.resolve(original.resolve() & p.second);
+
+ QPalette wp = w->palette();
+ wp.resolve(wp.resolve() & ~p.second);
+ wp.resolve(original);
+ wp.resolve(wp.resolve() | original.resolve());
+ original = wp;
+ }
+
+ w->setPalette(original);
QWidget *ew = embeddedWidget(w);
if (ew != w)
- ew->setPalette(p);
- styleSheetCaches->customPaletteWidgets.remove(w);
+ ew->setPalette(original);
}
- QVariant oldFont = w->property("_q_styleSheetWidgetFont");
- if (oldFont.isValid()) {
- w->setFont(qvariant_cast<QFont>(oldFont));
+
+ if (useStyleSheetPropagationInWidgetStyles) {
+ unsetStyleSheetFont(w);
+ QWidget *ew = embeddedWidget(w);
+ if (ew != w)
+ unsetStyleSheetFont(ew);
+ } else {
+ QVariant oldFont = w->property("_q_styleSheetWidgetFont");
+ if (oldFont.isValid()) {
+ w->setFont(qvariant_cast<QFont>(oldFont));
+ }
}
+
if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
embeddedWidget(w)->setAutoFillBackground(true);
styleSheetCaches->autoFillDisabledWidgets.remove(w);
}
}
+void QStyleSheetStyle::unsetStyleSheetFont(QWidget *w) const
+{
+ if (styleSheetCaches->customFontWidgets.contains(w)) {
+ QPair<QFont, uint> f = styleSheetCaches->customFontWidgets.value(w);
+ styleSheetCaches->customFontWidgets.remove(w);
+
+ QFont original = f.first;
+ original.resolve(original.resolve() & f.second);
+
+ QFont font = w->font();
+ font.resolve(font.resolve() & ~f.second);
+ font.resolve(original);
+ font.resolve(font.resolve() | original.resolve());
+
+ w->setFont(font);
+ }
+}
+
static void updateObjects(const QList<const QObject *>& objects)
{
if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
@@ -2658,6 +2716,7 @@ void QStyleSheetStyleCaches::objectDestroyed(QObject *o)
hasStyleRuleCache.remove(o);
renderRulesCache.remove(o);
customPaletteWidgets.remove((const QWidget *)o);
+ customFontWidgets.remove(static_cast<QWidget *>(o));
styleSheetCache.remove(o);
autoFillDisabledWidgets.remove((const QWidget *)o);
}
@@ -5846,24 +5905,42 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
// we should never override it.
if (w->objectName() == QLatin1String("qt_fontDialog_sampleEdit"))
return;
+
QWidget *container = containerWidget(w);
QRenderRule rule = renderRule(container, PseudoElement_None,
PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
- QFont font = rule.font.resolve(w->font());
- if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
- && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
- font = font.resolve(static_cast<QWidget *>(w->parent())->font());
- }
+ if (useStyleSheetPropagationInWidgetStyles) {
+ unsetStyleSheetFont(w);
- if (w->data->fnt == font)
- return;
+ if (rule.font.resolve()) {
+ QFont wf = w->font();
+ styleSheetCaches->customFontWidgets.insert(w, qMakePair(wf, rule.font.resolve()));
+
+ QFont font = rule.font.resolve(wf);
+ font.resolve(wf.resolve() | rule.font.resolve());
+ w->setFont(font);
+ }
+ } else {
+ QFont font = rule.font.resolve(w->font());
- w->data->fnt = font;
+ if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
+ && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
- QEvent e(QEvent::FontChange);
- QApplication::sendEvent(w, &e);
+ font = font.resolve(static_cast<QWidget *>(w->parent())->font());
+ }
+
+ if (w->data->fnt == font)
+ return;
+
+ w->data->fnt = font;
+
+ QEvent e(QEvent::FontChange);
+ QApplication::sendEvent(w, &e);
+ }
}
void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
index 9cd8cb889d..f622f7f419 100644
--- a/src/widgets/styles/qstylesheetstyle_p.h
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -149,6 +149,7 @@ private:
void unsetPalette(QWidget *);
void setProperties(QWidget *);
void setGeometry(QWidget *);
+ void unsetStyleSheetFont(QWidget *) const;
QVector<QCss::StyleRule> styleRules(const QObject *obj) const;
bool hasStyleRule(const QObject *obj, int part) const;
@@ -178,9 +179,12 @@ public:
QHash<const QObject *, QHash<int, bool> > hasStyleRuleCache;
typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
QHash<const QObject *, QRenderRules> renderRulesCache;
- QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered
QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
QSet<const QWidget *> autoFillDisabledWidgets;
+ // widgets whose palettes and fonts we have tampered. stored value pair is
+ // QPair<old widget value, resolve mask of stylesheet value>
+ QHash<const QWidget *, QPair<QPalette, uint> > customPaletteWidgets;
+ QHash<const QWidget *, QPair<QFont, uint> > customFontWidgets;
};
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
index 5b0ae29dc1..b52aa30239 100644
--- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -55,6 +55,7 @@ public:
~tst_QStyleSheetStyle();
private slots:
+ void init();
void repolish();
void numinstances();
void widgetsBeforeAppStyleSheet();
@@ -71,8 +72,12 @@ private slots:
void layoutSpacing();
#endif
void qproperty();
+ void palettePropagation_data();
void palettePropagation();
+ void fontPropagation_data();
void fontPropagation();
+ void widgetStylePropagation_data();
+ void widgetStylePropagation();
void onWidgetDestroyed();
void fontPrecedence();
void focusColors();
@@ -137,6 +142,12 @@ tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
{
}
+void tst_QStyleSheetStyle::init()
+{
+ qApp->setStyleSheet(QString());
+ QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, false);
+}
+
void tst_QStyleSheetStyle::numinstances()
{
QWidget w;
@@ -627,31 +638,80 @@ void tst_QStyleSheetStyle::namespaces()
QCOMPARE(BACKGROUND(pb2), red);
}
+void tst_QStyleSheetStyle::palettePropagation_data()
+{
+ QTest::addColumn<QString>("applicationStyleSheet");
+ QTest::addColumn<bool>("widgetStylePropagation");
+ QTest::newRow("Widget style propagation") << " " << true;
+ QTest::newRow("Widget style propagation, no application style sheet") << QString() << true;
+ QTest::newRow("Default propagation") << " " << false;
+ QTest::newRow("Default propagation, no application style sheet") << QString() << false;
+}
+
void tst_QStyleSheetStyle::palettePropagation()
{
- qApp->setStyleSheet("");
+ QFETCH(QString, applicationStyleSheet);
+ QFETCH(bool, widgetStylePropagation);
+
+ qApp->setStyleSheet(applicationStyleSheet);
+ QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, widgetStylePropagation);
+
QGroupBox gb;
- QPushButton *push = new QPushButton(&gb);
- QPushButton &pb = *push;
- push->setText("AsdF");
+ QLabel *label = new QLabel(&gb);
+ QLabel &lb = *label;
+ label->setText("AsdF");
gb.setStyleSheet("QGroupBox { color: red }");
- QVERIFY(COLOR(gb) == Qt::red);
- QVERIFY(COLOR(pb) == APPCOLOR(pb)); // palette shouldn't propagate
- gb.setStyleSheet("QGroupBox * { color: red }");
+ QCOMPARE(COLOR(gb), QColor(Qt::red));
- QVERIFY(COLOR(pb) == Qt::red);
- QVERIFY(COLOR(gb) == APPCOLOR(gb));
+ if (widgetStylePropagation) {
+ QCOMPARE(COLOR(lb), QColor(Qt::red)); // palette should propagate in standard mode
+ } else {
+ QCOMPARE(COLOR(lb), APPCOLOR(lb)); // palette shouldn't propagate
+ }
QWidget window;
+ lb.setParent(&window);
+ if (widgetStylePropagation) {
+ // In standard propagation mode, widgets that are not explicitly
+ // targeted do not have their propagated palette unset when they are
+ // unpolished by changing parents. This is consistent with regular Qt
+ // widgets, who also maintain their propagated palette when changing
+ // parents
+ QCOMPARE(COLOR(lb), QColor(Qt::red));
+ } else {
+ QCOMPARE(COLOR(lb), APPCOLOR(lb));
+ }
+ lb.setParent(&gb);
+
+ gb.setStyleSheet("QGroupBox * { color: red }");
+
+ QCOMPARE(COLOR(lb), QColor(Qt::red));
+ QCOMPARE(COLOR(gb), APPCOLOR(gb));
+
window.setStyleSheet("* { color: white; }");
- pb.setParent(&window);
- QVERIFY(COLOR(pb) == Qt::white);
+ lb.setParent(&window);
+ QCOMPARE(COLOR(lb), QColor(Qt::white));
+}
+
+void tst_QStyleSheetStyle::fontPropagation_data()
+{
+ QTest::addColumn<QString>("applicationStyleSheet");
+ QTest::addColumn<bool>("widgetStylePropagation");
+ QTest::newRow("Widget style propagation") << " " << true;
+ QTest::newRow("Widget style propagation, no application style sheet") << QString() << true;
+ QTest::newRow("Default propagation") << " " << false;
+ QTest::newRow("Default propagation, no application style sheet") << QString() << false;
}
void tst_QStyleSheetStyle::fontPropagation()
{
- qApp->setStyleSheet("");
+ QFETCH(QString, applicationStyleSheet);
+ QFETCH(bool, widgetStylePropagation);
+
+ qApp->setStyleSheet(applicationStyleSheet);
+ QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, widgetStylePropagation);
+
QComboBox cb;
cb.addItem("item1");
cb.addItem("item2");
@@ -661,7 +721,11 @@ void tst_QStyleSheetStyle::fontPropagation()
cb.setStyleSheet("QComboBox { font-size: 20pt; }");
QCOMPARE(FONTSIZE(cb), 20);
- QCOMPARE(FONTSIZE(*popup), viewFontSize);
+ if (widgetStylePropagation) {
+ QCOMPARE(FONTSIZE(*popup), 20);
+ } else {
+ QCOMPARE(FONTSIZE(*popup), viewFontSize);
+ }
QGroupBox gb;
QPushButton *push = new QPushButton(&gb);
QPushButton &pb = *push;
@@ -670,7 +734,11 @@ void tst_QStyleSheetStyle::fontPropagation()
gb.setStyleSheet("QGroupBox { font-size: 20pt }");
QCOMPARE(FONTSIZE(gb), 20);
- QVERIFY(FONTSIZE(pb) == buttonFontSize); // font does not propagate
+ if (widgetStylePropagation) {
+ QCOMPARE(FONTSIZE(pb), 20);
+ } else {
+ QCOMPARE(FONTSIZE(pb), buttonFontSize); // font does not propagate
+ }
gb.setStyleSheet("QGroupBox * { font-size: 20pt; }");
QCOMPARE(FONTSIZE(gb), gbFontSize);
QCOMPARE(FONTSIZE(pb), 20);
@@ -1796,6 +1864,138 @@ void tst_QStyleSheetStyle::styleSheetChangeBeforePolish()
QVERIFY(testForColors(image2, QColor(0x00, 0xFF, 0x00)));
}
+void tst_QStyleSheetStyle::widgetStylePropagation_data()
+{
+ QTest::addColumn<QString>("applicationStyleSheet");
+ QTest::addColumn<QString>("parentStyleSheet");
+ QTest::addColumn<QString>("childStyleSheet");
+ QTest::addColumn<QFont>("parentFont");
+ QTest::addColumn<QFont>("childFont");
+ QTest::addColumn<QPalette>("parentPalette");
+ QTest::addColumn<QPalette>("childPalette");
+ QTest::addColumn<int>("parentExpectedSize");
+ QTest::addColumn<int>("childExpectedSize");
+ QTest::addColumn<QColor>("parentExpectedColor");
+ QTest::addColumn<QColor>("childExpectedColor");
+
+ QFont noFont;
+ QFont font45; font45.setPointSize(45);
+ QFont font32; font32.setPointSize(32);
+
+ QPalette noPalette;
+ QPalette redPalette; redPalette.setColor(QPalette::WindowText, QColor("red"));
+ QPalette greenPalette; greenPalette.setColor(QPalette::WindowText, QColor("green"));
+
+ QLabel defaultLabel;
+
+ int defaultSize = defaultLabel.font().pointSize();
+ QColor defaultColor = defaultLabel.palette().color(defaultLabel.foregroundRole());
+ QColor redColor("red");
+ QColor greenColor("green");
+
+ // Check regular Qt propagation works as expected, with and without a
+ // non-interfering application stylesheet
+ QTest::newRow("defaults")
+ << QString() << QString() << QString()
+ << noFont << noFont << noPalette << noPalette
+ << defaultSize << defaultSize << defaultColor << defaultColor;
+ QTest::newRow("parent font propagation, no application style sheet")
+ << QString() << QString() << QString()
+ << font45 << noFont << noPalette << noPalette
+ << 45 << 45 << defaultColor << defaultColor;
+ QTest::newRow("parent font propagation, dummy application style sheet")
+ << "QGroupBox { font-size: 64pt }" << QString() << QString()
+ << font45 << noFont << noPalette << noPalette
+ << 45 << 45 << defaultColor << defaultColor;
+ QTest::newRow("parent color propagation, no application style sheet")
+ << QString() << QString() << QString()
+ << noFont << noFont << redPalette << noPalette
+ << defaultSize << defaultSize << redColor << redColor;
+ QTest::newRow("parent color propagation, dummy application style sheet")
+ << "QGroupBox { color: blue }" << QString() << QString()
+ << noFont << noFont << redPalette << noPalette
+ << defaultSize << defaultSize << redColor << redColor;
+
+ // Parent style sheet propagates to child if child has not explicitly
+ // set a value
+ QTest::newRow("parent style sheet color propagation")
+ << "#parentLabel { color: red }" << QString() << QString()
+ << noFont << noFont << noPalette << noPalette
+ << defaultSize << defaultSize << redColor << redColor;
+ QTest::newRow("parent style sheet font propagation")
+ << "#parentLabel { font-size: 45pt }" << QString() << QString()
+ << noFont << noFont << noPalette << noPalette
+ << 45 << 45 << defaultColor << defaultColor;
+
+ // Parent style sheet does not propagate to child if child has explicitly
+ // set a value
+ QTest::newRow("parent style sheet color propagation, child explicitly set")
+ << "#parentLabel { color: red }" << QString() << QString()
+ << noFont << noFont << noPalette << greenPalette
+ << defaultSize << defaultSize << redColor << greenColor;
+ QTest::newRow("parent style sheet font propagation, child explicitly set")
+ << "#parentLabel { font-size: 45pt }" << QString() << QString()
+ << noFont << font32 << noPalette << noPalette
+ << 45 << 32 << defaultColor << defaultColor;
+
+ // Parent does not propagate to child when child is target of style sheet
+ QTest::newRow("parent style sheet font propagation, child application style sheet")
+ << "#childLabel { font-size: 32pt }" << QString() << QString()
+ << font45 << noFont << noPalette << noPalette
+ << 45 << 32 << defaultColor << defaultColor;
+ QTest::newRow("parent style sheet color propagation, child application style sheet")
+ << "#childLabel { color: green }" << QString() << QString()
+ << noFont << noFont << redPalette << noPalette
+ << defaultSize << defaultSize << redColor << greenColor;
+}
+
+void tst_QStyleSheetStyle::widgetStylePropagation()
+{
+ QFETCH(QString, applicationStyleSheet);
+ QFETCH(QString, parentStyleSheet);
+ QFETCH(QString, childStyleSheet);
+
+ QFETCH(QFont, parentFont);
+ QFETCH(QFont, childFont);
+ QFETCH(QPalette, parentPalette);
+ QFETCH(QPalette, childPalette);
+
+ QFETCH(int, parentExpectedSize);
+ QFETCH(int, childExpectedSize);
+ QFETCH(QColor, parentExpectedColor);
+ QFETCH(QColor, childExpectedColor);
+
+ QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
+
+ qApp->setStyleSheet(applicationStyleSheet);
+
+ QLabel parentLabel;
+ parentLabel.setObjectName("parentLabel");
+ QLabel childLabel(&parentLabel);
+ childLabel.setObjectName("childLabel");
+
+ if (parentFont.resolve())
+ parentLabel.setFont(parentFont);
+ if (childFont.resolve())
+ childLabel.setFont(childFont);
+ if (parentPalette.resolve())
+ parentLabel.setPalette(parentPalette);
+ if (childPalette.resolve())
+ childLabel.setPalette(childPalette);
+ if (!parentStyleSheet.isEmpty())
+ parentLabel.setStyleSheet(parentStyleSheet);
+ if (!childStyleSheet.isEmpty())
+ childLabel.setStyleSheet(childStyleSheet);
+
+ parentLabel.ensurePolished();
+ childLabel.ensurePolished();
+
+ QCOMPARE(FONTSIZE(parentLabel), parentExpectedSize);
+ QCOMPARE(FONTSIZE(childLabel), childExpectedSize);
+ QCOMPARE(COLOR(parentLabel), parentExpectedColor);
+ QCOMPARE(COLOR(childLabel), childExpectedColor);
+}
+
QTEST_MAIN(tst_QStyleSheetStyle)
#include "tst_qstylesheetstyle.moc"