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>
This commit is contained in:
Aaron Kennedy 2015-06-28 21:31:30 +10:00 committed by Samuel Nevala
parent aaab800e16
commit 7293200ace
8 changed files with 375 additions and 51 deletions

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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();

View File

@ -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 (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());
if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
&& isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
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);
}
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

View File

@ -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;
};

View File

@ -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"