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 <Friedemann.Kleint@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
bb10
Volker Hilsheimer 2021-06-19 10:00:13 +02:00
parent 550e511ec8
commit c4f1b0f7c4
2 changed files with 24 additions and 1 deletions

View File

@ -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<QWidget*>();
for (auto child : childWidgets) {
repolish = child->d_func()->polished;
if (repolish)
break;
}
}
if (repolish)
proxy->repolish(this);
return;
}

View File

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