From 9803ba9b6f74f5ac18220fe145fe1fe4c8f70910 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 7 May 2020 15:46:11 +0200 Subject: Deprecate QGuiApplication::paletteChanged() signal Rather than have a paletteChanged() signal which can be connected to for tracking when the application palette has changed, then it is better to use the event that is sent to all windows and the application itself. That way it is easy for a window/widget or item that cares about the change to the application font to catch it in the event() function. [ChangeLog][QtGui][QGuiApplication] Deprecated paletteChanged() signal in favor of QEvent::ApplicationPaletteChanged. Change-Id: I95da211e30590e357007cc14d8ee266baceba7b3 Reviewed-by: Volker Hilsheimer --- src/gui/kernel/qguiapplication.cpp | 9 ++++-- src/gui/kernel/qguiapplication.h | 2 +- src/widgets/kernel/qapplication.cpp | 10 +++---- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 35 +++++++++++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 45df47730d..c6facb8ceb 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1900,10 +1900,11 @@ bool QGuiApplication::event(QEvent *e) if (topLevelWindow->flags() != Qt::Desktop) postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange)); } - } else if (e->type() == QEvent::ApplicationFontChange) { + } else if (e->type() == QEvent::ApplicationFontChange || + e->type() == QEvent::ApplicationPaletteChange) { for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) { if (topLevelWindow->flags() != Qt::Desktop) - postEvent(topLevelWindow, new QEvent(QEvent::ApplicationFontChange)); + postEvent(topLevelWindow, new QEvent(e->type())); } } else if (e->type() == QEvent::Quit) { // Close open windows. This is done in order to deliver de-expose @@ -3271,8 +3272,10 @@ QClipboard * QGuiApplication::clipboard() /*! \since 5.4 \fn void QGuiApplication::paletteChanged(const QPalette &palette) + \obsolete - This signal is emitted when the \a palette of the application changes. + This signal is emitted when the \a palette of the application changes. Use + QEvent::ApplicationPaletteChanged instead. \sa palette() */ diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 0c642d8ff5..6017cf513f 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -188,9 +188,9 @@ Q_SIGNALS: void commitDataRequest(QSessionManager &sessionManager); void saveStateRequest(QSessionManager &sessionManager); #endif - void paletteChanged(const QPalette &pal); void applicationDisplayNameChanged(); #if QT_DEPRECATED_SINCE(6, 0) + void paletteChanged(const QPalette &pal); void fontChanged(const QFont &font); #endif protected: diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index f5d857b623..d7919c9414 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1211,18 +1211,15 @@ void QApplicationPrivate::handlePaletteChanged(const char *className) // Setting the global application palette is documented to // reset any previously set class specific widget palettes. - bool sendPaletteChangeToAllWidgets = false; - if (!className && !widgetPalettes.isEmpty()) { - sendPaletteChangeToAllWidgets = true; + if (!className && !widgetPalettes.isEmpty()) widgetPalettes.clear(); - } QGuiApplicationPrivate::handlePaletteChanged(className); QEvent event(QEvent::ApplicationPaletteChange); const QWidgetList widgets = QApplication::allWidgets(); for (auto widget : widgets) { - if (sendPaletteChangeToAllWidgets || (!className && widget->isWindow()) || (className && widget->inherits(className))) + if (!widget->isWindow() && widget->inherits(className)) QCoreApplication::sendEvent(widget, &event); } @@ -1734,7 +1731,8 @@ bool QApplication::event(QEvent *e) #endif } - if (e->type() == QEvent::LanguageChange || e->type() == QEvent::ApplicationFontChange) { + if (e->type() == QEvent::LanguageChange || e->type() == QEvent::ApplicationFontChange || + e->type() == QEvent::ApplicationPaletteChange) { // QGuiApplication::event does not account for the cases where // there is a top level widget without a window handle. So they // need to have the event posted here diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 54ca37e638..991211062f 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -418,6 +418,7 @@ private slots: void winIdAfterClose(); void receivesLanguageChangeEvent(); void receivesApplicationFontChangeEvent(); + void receivesApplicationPaletteChangeEvent(); private: bool ensureScreenSize(int width, int height); @@ -4988,6 +4989,7 @@ void tst_QWidget::isOpaque() QVERIFY(!::isOpaque(&widget)); QApplication::setPalette(old); + QApplication::sendPostedEvents(&widget, QEvent::ApplicationPaletteChange); QCOMPARE(::isOpaque(&widget), old.color(QPalette::Window).alpha() == 255); } #endif @@ -11662,6 +11664,7 @@ public: ChangeEventWidget(QWidget *parent = nullptr) : QWidget(parent) {} int languageChangeCount = 0; int applicationFontChangeCount = 0; + int applicationPaletteChangeCount = 0; protected: bool event(QEvent *e) override { @@ -11669,6 +11672,8 @@ protected: languageChangeCount++; else if (e->type() == QEvent::ApplicationFontChange) applicationFontChangeCount++; + else if (e->type() == QEvent::ApplicationPaletteChange) + applicationPaletteChangeCount++; return QWidget::event(e); } }; @@ -11679,6 +11684,7 @@ public: ChangeEventWindow(QWindow *parent = nullptr) : QWindow(parent) {} int languageChangeCount = 0; int applicationFontChangeCount = 0; + int applicationPaletteChangeCount = 0; protected: bool event(QEvent *e) override { @@ -11686,6 +11692,8 @@ protected: languageChangeCount++; else if (e->type() == QEvent::ApplicationFontChange) applicationFontChangeCount++; + else if (e->type() == QEvent::ApplicationPaletteChange) + applicationPaletteChangeCount++; return QWindow::event(e); } }; @@ -11739,5 +11747,32 @@ void tst_QWidget::receivesApplicationFontChangeEvent() QApplication::setFont(origFont); } +void tst_QWidget::receivesApplicationPaletteChangeEvent() +{ + // Confirm that any QWindow or top level QWidget only gets a single + // ApplicationPaletteChange event when the font is changed + const QPalette origPalette = QApplication::palette(); + + ChangeEventWidget topLevel; + auto childWidget = new ChangeEventWidget(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + ChangeEventWindow ww; + ww.show(); + QVERIFY(QTest::qWaitForWindowExposed(&ww)); + ChangeEventWidget topLevelNotShown; + QPalette changedPalette = origPalette; + changedPalette.setColor(QPalette::Base, Qt::red); + QApplication::setPalette(changedPalette); + QCoreApplication::sendPostedEvents(0, QEvent::ApplicationPaletteChange); + QCOMPARE(topLevel.applicationPaletteChangeCount, 1); + QCOMPARE(topLevelNotShown.applicationPaletteChangeCount, 1); + // QWidget should not be passing the event on automatically + QCOMPARE(childWidget->applicationPaletteChangeCount, 0); + QCOMPARE(ww.applicationPaletteChangeCount, 1); + + QApplication::setPalette(origPalette); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v1.2.3