I'm working on a Qt application (deploying to Qt 5.11, but I'm testing on Qt 5.14) that needs to run on a variety of projectors. At least one of these projectors reports a physical size of over one metre, which results in only 32.5 dpi reported to the Linux OS (compared to the default of 96 dpi). The effect of this setting on our Qt app is that all text becomes unreadably small:
It can be reproduced on any system by running
xrandr --dpi 32.5
before starting the application.
We could configure the system dpi differently, but there are reasons not to: this dpi is actually in the right ballpark (it's even too high), we may want to use it in other applications, and customers may use their own projector which might break our manual configuration.
The safe approach for this particular use case is to pretend we're still living in the stone age: ignore the system dpi setting and just use a 1:1 mapping between device-independent pixels and device pixels. The High DPI displays documentation says:
The
Qt::AA_DisableHighDpiScaling
application attribute, introduced in Qt 5.6, turns off all scaling. This is intended for applications that require actual window system coordinates, regardless of environment variables. This attribute takes priority overQt::AA_EnableHighDpiScaling
.
So I added this as the first line in main
(before the QApplication
is created):
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
However, it seems to have no effect; text is still unreadably small. I also tried this in various combinations with:
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);
QCoreApplication::setAttribute(Qt::AA_Use96Dpi);
Nothing has any visible effect effect.
What does work is setting QT_AUTO_SCREEN_SCALE_FACTOR=1
in the environment. If I understand correctly, this would enable scaling rather than disable it, but setting it to 0
does not work!
Similarly, if I enable Qt::AA_EnableHighDpiScaling
in code like this, everything becomes readable:
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
What also works to some extent is hardcoding the font size (found here):
QFont font = qApp->font();
font.setPixelSize(11);
qApp->setFont(font);
However, margins in the layout still seem to be scaled, so this results in a very cramped (albeit usable) layout.
What also works is setting QT_FONT_DPI=96
in the environment (this variable seems to be undocumented, but it works in Qt 5.11 and 5.14 at least).
Either there are bugs in Qt, or more likely, I'm misunderstanding something. How come that enabling the scaling seems to disable it and vice versa?
Edit: just tested on Qt 5.11 too, although it's on another system. There, neither QT_AUTO_SCREEN_SCALE_FACTOR=1
nor QT_AUTO_SCREEN_SCALE_FACTOR=0
works, so it seems we are dealing with Qt bugs to some extent after all. Maybe related:
So how can I make it work reliably in all cases?
Select Display > Change the size of text, apps, and other items, and then adjust the slider for each monitor. Right-click the application, select Properties, select the Compatibility tab, and then select the Disable display scaling on high DPI settings check box.
But sometimes this feature for some specific apps can cause compatibility issues, unreadable texts, blurry signs, and ultimately app crashes. It is quite a headache if you are working on a 2160p resolution or higher. There are many ways to disable the default display scaling feature on High DPI settings.
This option was previously known as “Disable display scaling on high DPI settings”, and it does the same thing. System: Windows will use its normal behavior. Applications that don't respect system DPI settings will be “bitmap stretched” to appear larger so they're more easily readable, but will often appear blurry.
High DPI scaling override Application: The application will be unaware of high DPI and will not be scaled; System: The application will again be unaware of high DPI and the system will scale it; System (Enhanced): This is only available in Windows 10 (1703)+.
Here's what I did in the end to forcibly disable any scaling on Qt 5.11:
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
if (qgetenv("QT_FONT_DPI").isEmpty()) {
qputenv("QT_FONT_DPI", "84");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With