From c4f1b0f7c477e87bc2bee3611807cbdf7b5f8ec4 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Sat, 19 Jun 2021 10:00:13 +0200 Subject: [PATCH] Repolish child widgets when parent style sheet changes If a child widget that is affected by the parent's style sheet is polished (because it's been shown explicitly, for instance by a layout), then it must be repolished when the parent's style sheet changes, even if the parent itself has not been polished yet. Since the style sheet is set on the parent widget, we must repolish the parent (which will repolish the entire widget tree), not just the individual children and grand children. Fixes: QTBUG-76945 Task-number: QTBUG-39427 Task-number: QTBUG-18958 Change-Id: I7bca9ee1badc07202fa05dc97f440f4ca6c9517d Reviewed-by: Friedemann Kleint Reviewed-by: Qt CI Bot Reviewed-by: Andy Shaw --- src/widgets/kernel/qwidget.cpp | 11 ++++++++++- .../qstylesheetstyle/tst_qstylesheetstyle.cpp | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a5ad101201..95d38c4882 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2575,7 +2575,16 @@ void QWidget::setStyleSheet(const QString& styleSheet) } if (proxy) { // style sheet update - if (d->polished) + bool repolish = d->polished; + if (!repolish) { + const auto childWidgets = findChildren(); + for (auto child : childWidgets) { + repolish = child->d_func()->polished; + if (repolish) + break; + } + } + if (repolish) proxy->repolish(this); return; } diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 27500173c8..a4ce5ac77e 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -77,6 +77,7 @@ private slots: void cleanup(); void repolish(); void repolish_without_crashing(); + void repolish_children(); void numinstances(); void widgetsBeforeAppStyleSheet(); void widgetsAfterAppStyleSheet(); @@ -438,6 +439,19 @@ void tst_QStyleSheetStyle::repolish_without_crashing() QCOMPARE(COLOR(*label), QColor(Qt::red)); } +void tst_QStyleSheetStyle::repolish_children() +{ + QWidget parent; + parent.setStyleSheet("QPushButton { color: red; background: white }"); + QPushButton p2(&parent); + // a layout would call show, triggering a polish of the child while + // the parent on which the style sheet is set remains unpolished + p2.show(); + QCOMPARE(BACKGROUND(p2), Qt::white); + parent.setStyleSheet("QPushButton { color: red; background: red }"); + QCOMPARE(BACKGROUND(p2), Qt::red); +} + void tst_QStyleSheetStyle::widgetStyle() { qApp->setStyleSheet(QString());