What should I use instead of QDesktopWidget::resized in Qt 6?
-
I'm in the process of converting a project from Qt 5 to Qt 6. I previously used the signal
QDesktopWidget::resized
to be notified of when anything about the current screen configuration changed, be it the resolution of one screen or the arrangement of multiple screens.However,
QDesktopWidget
has been removed from Qt 6, and I don't see anything that replaces this specific signal.While
QScreen
is obviously intended to be used as a replaced toQDesktopWidget
, and I can use various signals ofQScreen
to be notified of the changes of one specific screen, there doesn't appear to be any signal that will notify me of changes to any screen, regardless of what that change is.There also doesn't seem to be an equivalent signal on
QGuiApplication
either.The only solution I can think of is to make use of the
QGuiApplication::screenAdded
signal, and every time a new screen is added, connect to itsgeometryChanged
signal. But, quite frankly, that totally sucks. Not only is it more crufty code to do something that used to be a one liner, it also now means I'm going to have multiple signals fire every time something about the screen configuration changes, rather than just one. And I don't know how many signals will fire because any one configuration operation is not guaranteed to change every screen!Surely there's a better way. How do I do this in Qt 6?
-
I'm in the process of converting a project from Qt 5 to Qt 6. I previously used the signal
QDesktopWidget::resized
to be notified of when anything about the current screen configuration changed, be it the resolution of one screen or the arrangement of multiple screens.However,
QDesktopWidget
has been removed from Qt 6, and I don't see anything that replaces this specific signal.While
QScreen
is obviously intended to be used as a replaced toQDesktopWidget
, and I can use various signals ofQScreen
to be notified of the changes of one specific screen, there doesn't appear to be any signal that will notify me of changes to any screen, regardless of what that change is.There also doesn't seem to be an equivalent signal on
QGuiApplication
either.The only solution I can think of is to make use of the
QGuiApplication::screenAdded
signal, and every time a new screen is added, connect to itsgeometryChanged
signal. But, quite frankly, that totally sucks. Not only is it more crufty code to do something that used to be a one liner, it also now means I'm going to have multiple signals fire every time something about the screen configuration changes, rather than just one. And I don't know how many signals will fire because any one configuration operation is not guaranteed to change every screen!Surely there's a better way. How do I do this in Qt 6?
@Guy-Gizmo said in What should I use instead of QDesktopWidget::resized in Qt 6?:
Surely there's a better way. How do I do this in Qt 6?
ok, no longer a one-liner but also no rocket-science:
auto connectGeoChanged = [this](QScreen* s) { connect(s, &QScreen::geometryChanged, this, &Foo::onGeometryChanged); }; connect(qApp, &QGuiApplication::screenAdded, this, connectGeoChanged); const auto screens = QGuiApplication::screens(); for (auto s : screens) connectGeoChanged(s);
-
@Christian-Ehrlicher I do mention connecting to
QGuiApplication::screenAdded
in my original post and the trouble here is that, instead of getting one signal when the system screen configuration changes, I get multiple depending on how many screens are involved.I could of course use a
QTimer
that gets started on the firstgeometryChanged
signal / call toonGeometryChanged()
, reset on each subsequent signal, and so will fire when thegeometryChanged
signals from each screen have all finished. But this solution isn't great for a number of reasons:- It's a race condition: I don't know long it will take for each screen signal to fire, and using too short of a timer could result in me erroneously processing the change to the system screen configuration multiple times. (Though practically speaking they'll probably all fire within a few milliseconds of each other, if not within the same millisecond.)
- My handler now is delayed however long it takes the timer to fire rather than handling it immediately, leaving a brief period of discontinuity where my app's internal representation of the current screen configuration is out-of-date. (Another race condition.)
- It's a whole lot of crufty code to do something that used to be a simple one liner
If that's what it takes then I'll do it, and I can probably find a way to factor it into its own function or class to keep the cruftiness sequestered somewhere appropriate and out of my main code. But I'm really hoping there's a more elegant way of handling this, especially a method that avoids 1 and 2 above.
That all said, it strikes me that the right way to handle this would be for
QGuiApplication
to have a signal that fires when the overall screen configuration changes, duplicating the functionality ofQDesktopWidget::resized
, sinceQGuiApplication
already has several signals related to the system screen configuration. Maybe I'll file a feature request for that. -
instead of getting one signal when the system screen configuration changes, I get multiple depending on how many screens are involved.
You don't get one signal - you get one signal per change, see https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/kernel/qdesktopwidget.cpp?h=5.15.2#n187
My code does exactly the same as QDesktopWidget would do for a geometry change.