Repaint the whole dark canvas when the application palette changes

After a live light/dark switch only the sheet changed colors; the
viewport around it kept the previous palette. Qt repaints a widget on
an application palette change only when the widget's own palette
changed with it, and under the folio tab widget's style sheet it does
not, so the only repaints came from the scene and covered the scene
rectangle alone. PaletteGraphicsView now watches the application
object for ApplicationPaletteChange, the one receiver Qt always
notifies, and repaints its whole viewport.

The test paletteViewFollowsTheApplicationUnderAStyleSheet now also
requires a full-viewport repaint after each switch, before anything
asks the view for a rendering.
This commit is contained in:
Jeff Patterson
2026-09-19 15:41:50 -05:00
parent 6404612014
commit 50792ba1ad
3 changed files with 40 additions and 1 deletions
+20
View File
@@ -20,6 +20,7 @@
#include "qetpalette.h"
#include <QApplication>
#include <QEvent>
#include <QPainter>
#include <QPaintEvent>
#include <QStyleHintReturnMask>
@@ -29,11 +30,13 @@
PaletteGraphicsView::PaletteGraphicsView(QWidget *parent) :
QGraphicsView(parent)
{
qApp->installEventFilter(this);
}
PaletteGraphicsView::PaletteGraphicsView(QGraphicsScene *scene, QWidget *parent) :
QGraphicsView(scene, parent)
{
qApp->installEventFilter(this);
listenToScene(scene);
}
@@ -78,6 +81,23 @@ void PaletteGraphicsView::listenToScene(QGraphicsScene *scene)
connect(scene, &QGraphicsScene::changed, this, [](const QList<QRectF> &) {});
}
/**
@brief PaletteGraphicsView::eventFilter
Repaint the whole viewport when the application palette changes. Qt
sends that change to the application object and then repaints only
the widgets whose own palette changed with it, which under a style
sheet is not the case (see invertsLightness()): the scene would then
repaint only what it updates itself, and the viewport around the
sheet would keep the colors of the previous palette. The filter sits
on the application object, the one receiver Qt always notifies.
*/
bool PaletteGraphicsView::eventFilter(QObject *watched, QEvent *event)
{
if (watched == qApp && event->type() == QEvent::ApplicationPaletteChange)
viewport()->update();
return QGraphicsView::eventFilter(watched, event);
}
/**
@brief PaletteGraphicsView::paintEvent
Paints as QGraphicsView on a light palette, inverted on a dark one.