HiDPI monitors

Elvis Stansvik elvstone at gmail.com
Sat Jan 16 13:26:03 GMT 2021


Nice! Just a small comment about

> MySetting = 100 / int(QScreen.devicePixelRatio(app.primaryScreen()))

Here you are assuming that the application is on the primary screen.
In a multi-monitor setup, it may be on another screen with a different
device pixel ratio. It's possibly a better idea to call
QPaintDevice::devicePixelRatio() on the widget that will hold your
matplotlib plots.

Also, the application may be moved between screens, which you should
ideally listen for (there are some Qt mechanisms for this I believe,
screenChanged signal, though I've found it a bit unreliable at times),
and if it happens, re-create your matplotlib plots with the correct
DPI passed in (calculated from the new screen the widget is on), and
also re-create any pixmaps you may have created in terms of physical
pixels (if you have any like that).

How much of this you want to bother with is up to you of course :) You
may decide it's enough if the user has to restart the application if
he/she wants it on another screen.

HiDPI really is a pain :)

Cheers,
Elvis

Den fre 15 jan. 2021 kl 17:34 skrev ullix <ullix at urkam.de>:
>
> My struggle with HiDPI monitors has come to an at least workaround solution thanks to your responses, so many thanks!
> I'll try to summarize:
>
> PyQt(5) applications will behave well with this command:
>
> QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
>
> Whether this next command will also be needed depends on your explicit (perhaps implicit) use of pixmaps with HiDPIs available
> I had no benefit from it
>
> QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
>
> Unfortunately, matplotlib is separate from this and needs its own adaptation of settings. This can be done by setting the 'dpi=' parameter in every call to figure:
> matplotlib.pyplot.figure(num=None, figsize=None, dpi=MySetting, .... )
>
> But MySetting is a bit tricky: it basically must reverse the scaling. The default dpi is: MySetting = 100. So, when your scaling is 200%, then set MySetting=50. Is your scaling 300%, then set MySetting=33.
>
> I don't know if there is a single command which could set dpi for the session?
>
> Thankfully the "devicePixelRatio" of QScreen basically has Scaling/100, i.e. the values 1, 2, 3 for the above examples. Therefore you can set:
> MySetting = 100 / int(QScreen.devicePixelRatio(app.primaryScreen()))
>
> In the rare case that you do not have several 4k and 8k monitors to test with :-( you can use Xephyr as suggested by VA.
> Though when I tried the examples refernenced by him  https://indigo.re/posts/2020-05-18-hidpi-testing.html each one crashed on my system! But in my need I came back and just tried the small script and it worked! Script: https://gitlab.com/hydrargyrum/attic/blob/master/xephyr-run-cmd/xephyr-run-cmd
>
> I can now start my program and run it in proper scale with this command:
> ./xephyr-run-cmd -dpi 200 -screen 4000x2000 -- ./geigerlog
>
> And lastly a screenshot on a real 8k monitor on Win10:
> Full WidthxHeight is 2732x1443 (open it);
> and the user says he can even move it back and forth between an 8K and a FullHD monitor without distortion except for a wobble in the transition !!?
>
> Thanks again,
>
> ullix
>
>


More information about the PyQt mailing list