When changing the scaling factor of one of the monitors to any value, Qt doesn't update hdpi settings accordingly. QScreen::devicePixelRatio and QPaintDevice::devicePixelRatio return the same values for the whole lifetime of the process, and the layouting is likely to not work if the system's scaling configuration doesn't match the configuration on process start (see image). With scaling factor = 2 QScreen:: physicalDotsPerInch and QScreen::logicalDotsPerInch become twice as high as they should be.
Before creating QApplication the following settings are used:
Qt 5.15.0 is affected by the described problem. Contrary Qt 5.14.0 is not affected by the problem, the properties QScreen::devicePixelRatio, QScreen:: physicalDotsPerInch and QScreen::logicalDotsPerInch immediately have correct values, and the geometry of all widgets correctly changes.
In the following table properties of QScreen before and after changing the scaling factor from 1 to 2 are listed under both Qt versions.
|Qt 5.14.0 - scaling=1||Qt 5.14.0 - scaling=2||Qt 5.15.0 - scaling=1||Qt 5.15.0 - scaling=2|
The testcase project is contained in the attached zip file:
- Create the project with cmake from the attached example zip file (tested configuration: generator of project: Visual Studio 14 2015, Optional platform for generator: x64, select option 'Use default native compilers', Qt5_DIR: cmake/qt5 of Qt 5.15.0)
- Compile project (if Visual Studio was configured as the generator: open qt_hdpi.sln, build the whole solution, set qt_hdpi as the startup project, copy qt dlls and plugin/platforms folder into the bin directory manually)
- Set scaling factor 1 for the screen where the test will be performed
- Start the test from executable ./bin/qt_hdpi .The test widget below should open. Move the widget on the display where the scaling factor will be changed. Clicking on button 'Show screen config' opens a panel with the configuration of the displays and the widget (each display has its own tab, the Widget config is on the first tab).
- Set scaling factor 2 while the application is running. Observe that the widgets look broken like in the first image above.
- Refresh the display panel by clicking on the 'Show screen config' button. Observe that devicePixelRatio on the test display and the Widget is still 1, although it should equal 2.
- If the widgets are moved between displays, they correctly recompute the geometry. But reinitializing the widget with the display configurations through the 'Show screen config' button or the 'Refresh' button (deletes the tab widget and reconstructs it) will result in a broken widget like seen above.
For details of the platform see
- Qt 15.5.0, x64
- MS Visual Studio Professional 2015 (Version 14, Update 3)
- Cmake 3.14.3
- Windows 10 x64 (Version 1803)