QOpenGlWidget - Best way to detect monitor/DPI change?
-
wrote on 4 Jun 2023, 13:04 last edited by
I've noticed that a widget can override a resizeEvent and will be notified when the DPI has changed (or at least the monitor).
I was just trying this with QOpenGlWidget and it doesn't seen to have this functionality, how then should I instead determine when the DPI changes? I'd rather not do it in some time based approach (polling every X ms to check if its different)
-
I've noticed that a widget can override a resizeEvent and will be notified when the DPI has changed (or at least the monitor).
I was just trying this with QOpenGlWidget and it doesn't seen to have this functionality, how then should I instead determine when the DPI changes? I'd rather not do it in some time based approach (polling every X ms to check if its different)
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
I was just trying this with QOpenGlWidget and it doesn't seen to have this functionality
Since QOpenGLWidget is a QWidget it also has a resizeEvent.
-
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
I was just trying this with QOpenGlWidget and it doesn't seen to have this functionality
Since QOpenGLWidget is a QWidget it also has a resizeEvent.
wrote on 4 Jun 2023, 21:41 last edited byI understand that, but I also mean it does not get the event even in resizeEvent or resizeGl
-
I understand that, but I also mean it does not get the event even in resizeEvent or resizeGl
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
but I also mean it does not get the event even in resizeEvent or resizeGl
My QOpenGLWidget derived class does get a resizeEvent when I resize the widget. Please provide a minimal, compilable example to reproduce your problem.
-
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
but I also mean it does not get the event even in resizeEvent or resizeGl
My QOpenGLWidget derived class does get a resizeEvent when I resize the widget. Please provide a minimal, compilable example to reproduce your problem.
wrote on 5 Jun 2023, 05:00 last edited byI also do when I resize the widget, my question is when I change the monitor it does not get this event. Other widgets do
-
wrote on 5 Jun 2023, 07:10 last edited by
Maybe you are lucky (and maybe just on a single OS) that you'll get a resizeEvent when switching monitors because the OS does something funny. You should be looking for moveEvent instead because the widget is definitely moved but only maybe resized.
-
Maybe you are lucky (and maybe just on a single OS) that you'll get a resizeEvent when switching monitors because the OS does something funny. You should be looking for moveEvent instead because the widget is definitely moved but only maybe resized.
wrote on 5 Jun 2023, 08:44 last edited by NightShadeI 6 May 2023, 13:36This is cross platform behaviour, I get the same on OSX and WindowsI don't want moveEvent since that's way too spammy for my purposesA trivial solution would be to use a QTimer and check if the screens devicePixelRatio has changed, and then handle the screen change event from that , but it's not ideal eitherThe resize event makes sense due to the DPI change, so the real width and height you are working with are different!!Ah actually my bad, indeed we do not get resize events, I was only getting them when dragging over a window bigger than the smaller monitors size, which makes sense since that is a resize to fit the window
I guess then the question is how should I detect a DPI change (and I say DPI since the systems window scaling might change, it's not necessarily a monitor related one)?
-
This is cross platform behaviour, I get the same on OSX and WindowsI don't want moveEvent since that's way too spammy for my purposesA trivial solution would be to use a QTimer and check if the screens devicePixelRatio has changed, and then handle the screen change event from that , but it's not ideal eitherThe resize event makes sense due to the DPI change, so the real width and height you are working with are different!!Ah actually my bad, indeed we do not get resize events, I was only getting them when dragging over a window bigger than the smaller monitors size, which makes sense since that is a resize to fit the window
I guess then the question is how should I detect a DPI change (and I say DPI since the systems window scaling might change, it's not necessarily a monitor related one)?
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
I guess then the question is how should I detect a DPI change (and I say DPI since the systems window scaling might change, it's not necessarily a monitor related one)?
Take a look at QScreen
-
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
I guess then the question is how should I detect a DPI change (and I say DPI since the systems window scaling might change, it's not necessarily a monitor related one)?
Take a look at QScreen
wrote on 6 Jun 2023, 00:25 last edited byThanks the signals here ended up solving my issue , for now just subscribing to logicalDPI changes and screen changes. Will mark as solved
-
-
Thanks the signals here ended up solving my issue , for now just subscribing to logicalDPI changes and screen changes. Will mark as solved
wrote on 6 Jun 2023, 06:49 last edited by@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
Thanks the signals here ended up solving my issue , for now just subscribing to logicalDPI changes and screen changes. Will mark as solved
I am not sure I entirely understand what you are saying here. I believe that logicalDPI changes occur when you change the scaling of a single monitor in the OS's settings. Or is there something I am missing?
Here is some code that is called within moveEvent in our software:
qreal new_pixel_ratio = mainwindow->windowHandle()->screen()->logicalDotsPerInchY()/qApp.primaryScreen()->logicalDotsPerInchY(); if(new_pixel_ratio != this->pixel_ratio) { this->pixel_ratio = new_pixel_ratio; emit pixelRatioChanged(this->pixel_ratio); }
This has worked really well so far. Note, that this is not the screen scaling itself, but the scaling relative to the primary screen. All our sizes are related to the font height given by the QFontMetrics of the default font which will be computed for the primary screen; hence the scaling relative to the primary screen.
-
@NightShadeI said in QOpenGlWidget - Best way to detect monitor/DPI change?:
Thanks the signals here ended up solving my issue , for now just subscribing to logicalDPI changes and screen changes. Will mark as solved
I am not sure I entirely understand what you are saying here. I believe that logicalDPI changes occur when you change the scaling of a single monitor in the OS's settings. Or is there something I am missing?
Here is some code that is called within moveEvent in our software:
qreal new_pixel_ratio = mainwindow->windowHandle()->screen()->logicalDotsPerInchY()/qApp.primaryScreen()->logicalDotsPerInchY(); if(new_pixel_ratio != this->pixel_ratio) { this->pixel_ratio = new_pixel_ratio; emit pixelRatioChanged(this->pixel_ratio); }
This has worked really well so far. Note, that this is not the screen scaling itself, but the scaling relative to the primary screen. All our sizes are related to the font height given by the QFontMetrics of the default font which will be computed for the primary screen; hence the scaling relative to the primary screen.
wrote on 6 Jun 2023, 07:52 last edited by NightShadeI 6 Jun 2023, 08:05Interesting, ill admit I don't full understand what your code is doing, I was more looking for a way to detect DPI changes without using a timer/movement based approach , only doing work when it needs doing, so now I do something like this
QObject::connect(qApp->primaryScreen(), &QScreen::logicalDotsPerInchChanged, [this](qreal screen_geometry) { qDebug() << "logical DPI changed:" << QWidget::window()->screen()->devicePixelRatio(); // Such as when I change OS DPI settings , like you mention }); QObject::connect(QWidget::window()->windowHandle(), &QWindow::screenChanged, [this](QScreen* screen) { qDebug() << "Screen changed:" << QWidget::window()->screen()->devicePixelRatio(); // Such as when I drag over to a different monitor });
I then call some handler if need be to tell it to use this new DPI which works perfectly. I'm only using this DPI to recalculate some orthogonal matrices and viewports
Edit: If I understand right, you are updating the ratio yourself based on the windows current screen and the primary screen? Won't that impact the pixel ratio (through OS settings) if you modify the primary screen but not the screen its currently on? Directly using
QScreen::devicePixelRatio
works for me and is clean, sounds like slightly different use cases :)
1/11