9

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:

Screenshot of problem

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 over Qt::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?

Thomas
  • 174,939
  • 50
  • 355
  • 478

1 Answers1

4

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");
    }
Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Does hard-coding the `QT_FONT_DPI` provide satisfying results on all devices (aka. resolutions)? In the latest time I noticed that the High DPI issues were less often reported. (Maybe, the customers accomplished to stay away from certain H/W.) A colleague showed me his experiments while a 4K display (integrated laptop monitor) was combined with non-4K displays (desktop monitors). It left me somehow hopeless... – Scheff's Cat May 29 '21 at 12:28
  • I just see that you're on X11. In our case, Windows is our primary platform. That may have an effect as well... :-( The hint to disable high DPI handling, I already read some years ago somewhere. It's a tragedy. – Scheff's Cat May 29 '21 at 12:31
  • We're also on Qt 5.11 still, which is pretty old... newer versions might have fewer problems. – Thomas May 31 '21 at 07:33