Morten Johan Sørvig

High-DPI Support in Qt 5.6

Published Tuesday January 26th, 2016
16 Comments on High-DPI Support in Qt 5.6
Posted in Dev Loop

Qt 5.6 brings improved high-DPI support, in the form of better support for the devicePixelRatio scaling mode. In this blog we’ll look at how to configure and enable it, from the perspective of a Qt application user and a Qt application developer.

unscaled sammegame vs scaled samegame

Unscaled sammegame vs scaled samegame

Developing applications won’t be covered in depth now, but has to some extent been covered earlier. The short story is that applications generally benefit from this high-DPI mode even without modifications.

This high-DPI mode is a virtualization mode, where there is not necessarily a 1:1 correspondence between a unit in the QWidget/Quick item coordinate system and a pixel on screen. One “unit” then has constant visual size across systems with different display densities, and actual screen pixel density is to a large degree hidden from the application.

Dots Per Inch (DPI) is the traditional measurement for display density, where a standard density display has a DPI value of 72 or 96. Qt as always scaled fonts automatically according to the system DPI, and then the application code was responsible for scaling hardcoded layout sizes. The Qt styles would to a certain degree adapt to the font size. The devicePixelRatio mode is different in two ways: First, the display density is expressed as a scale factor — the devicePixelRatio in Qt — ranging from 1 to n. Second, the scale factor is applied lower in the stack (on the Apple platforms at the OS level), and is less directly used in application code.

There is often a fixed relation between DPI and scale factors on a given platform:

Android DPI and scale factors
class DPI Scale Factor
ldpi 120 0.7
mdpi 160 1
hdpi 240 1.5
xhdpi 320 2.0
xxhdpi 480 3.0
xxxhdpi 640 4.0

From stackoverflow. Quiz: Why is 1x 160 DPI on Android, compared to ~90 on desktop?

Demonstrating rendering at display densities on a blog is difficult. What we can do instead change the devicePixelRatio Qt sees while keeping the display scale factor constant. This results in larger visual sizes at higher devicePixelRatios:


The Qt Labs Controls SpinBox at various scale factors, including the unsupported 1.5x.

Enabling high-DPI support: Qt needs to be provided with a scale factor for all displays on the system. There are several possible sources for the scale factors: The values can be provided directly by the OS, Qt can compute them based on traditional display metrics provided by the operating system (such as the DPI value), or the user or developer can provide them directly. The mechanisms for setting and enabling the sources are environment variables and application attributes.

Historical Sidebar:Qt 5.4 and Qt 5.5 on X11 and Windows supports setting the devicePixelRatio with QT_DEVICE_PIXEL_RATIO=n (integer only). This setter has now been deprecated and replaced with several others, as described below.

Let’s look at three different cases:

Case I: The operating implements high-DPI scaling and provides a scale factor.

This is the situation for the Apple platforms – the OS enables the high-dpi mode, and Qt and the application come along for the ride.

This is also the case for Qt on Wayland when the Wayland display server is configured with scaling enabled:

./weston --scale 2

For the experimentally inclined, Qt for Native Client also gets a scale factor set when browser zoom is activated.

Case II: Qt supports the scaling and computes a scale factor.

Supported platforms: X11, Windows, Android, Eglfs

Qt can enable devicePixelRatio scaling on platforms that do not support it natively. This can be done via an environment variable or an application attribute in the application source code:


Qt will then query the the operating system for display metrics using native API, or in the eglfs case fall back on QT_QPA_EGLFS_PHYSICAL_WIDTH, QT_QPA_EGLFS_PHYSICAL_HEIGHT and the display pixel size.

Enabling can also be vetoed, either by environment variable or by the application:


The use-cases for vetoing are “I’m not getting correct DPI values from my displays” and “my application really needs to work in display pixels”. Note that this vetoing only disables “Case II” scaling: Qt can of course not change how the OS works, and manual set scale factors (below) are also kept as as a separate case.

Case III: Setting a scale factor manually.
Supported Cross-platform.


Sets the scale factors for all screens. Screen order is QApplication::screens() order. This setter assumes that text has already been properly scaled for the display, through the DPI setting, and then scales the rest of the user interface to match.


Sets a global scale factor for the entire application, scaling everything uniformly. This final option is useful for development and testing, and allows you to test any scale factor on any hardware. It can also be useful for some embedded scenarios – for example if you are targeting a single display type with a full-screen application: tweak the scale factor until the UI has the correct visual size.

The finer points:

Q: What happens if I use more than one of these setters?
A: The scale factors are multiplicative. Setting QT_SCALE_FACTOR=2 on a 2x device gives an effective devicePixelRatio of 4.

Q: Are non-integer scale factors supported?
A: Qt uses qreal in the API, and will allow setting non-integer scale factors via QT_SCALE_FACTOR. However, Qt does not guarantee that graphics and styles will be glitch-free in that case. Styles may break first: the fusion style is generally most scalable. The Qt platform plugins round the reported scale factors to the nearest integer.

Q: Could a scale factor of 0.5 allow me to work in device pixels on a 2x device?
A: That’s uncharted waters, but a possibility.

The new High-DPI functionality is part of Qt 5.6 release. To try it out, please check out the Qt 5.6 Beta.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Dev Loop


Michael says:

Regarding your Quiz why is 160 dpi ~ 100% on android:

The relevant resolution for human is not the dpi on the screen, but the dots per arc second in your eyes field of view.

As the typical smart phone is closer to your eye as the desktop screen the nominal resolution of 100% representing 96dpi in 1m distance is about the same dots per arcsec as 160 dpi in about 0.6 m distance:

96 dpi * 1m ~ 160 dpi * 0.6m

The same number of lines must be shown on a smaller distance: 1m vs 0.6 m


Morten Johan Sørvig Morten Johan Sørvig says:

Correct – it’s the viewing distance (that’s my take on it at least).

Ben Lau Ben Lau says:

It is nice feature!

But I have a problem to upgrade it. Since Qt 5.5, the command line installer is broken. I can’t find a way to setup a CI service like travis / to build with Qt 5.5.

Any solution for this problem?

Morten Johan Sørvig Morten Johan Sørvig says:


Unfortunately I have no idea on what might have happened to the command line installer.

Stephen Chu says:

> The Qt platform plugins round the reported scale factors to the nearest integer.

Does that mean it’s still effectively integer-only? What happens to Windows with 150% DPI scale?

Morten Johan Sørvig Morten Johan Sørvig says:

Yes, unless you set/correct it manually with QT_SCALE_FACTOR. 150% should then go to 2x.

Michael Tims says:

Is this going to change? I’d expect these real vales to be floating point values when necessary. Otherwise you lose the effect for cross-platform scaling

Nikita Krupenko says:

For mobile devices we have devicePixelRatio 1.0 for 160 dpi. Shouldn’t we have devicePixelRatio 0.5 for 96 dpi desktop screen?

Morten Johan Sørvig Morten Johan Sørvig says:

I would say no – that the scale factor has the viewing distance of the device factored in (things can be smaller on hand-held devices)

Of course touch devices require larger touch targets again, but that’s a different aspect.

danny says:

I suppose this does not reduce the quality of font hinting, right?

Morten Johan Sørvig Morten Johan Sørvig says:

There have been some font issues, but in general I would say fonts look good.

Allan Jensen says:

It disables it currently.

Daniel says:

It’s great that this is getting more attention. The current implementation (for Windows and Mac) is a bit shaky.

Any chance that the following issues will get fixes? (not fixed, at least not in 5.4.1) (this is a big problem for us) (big issue for multi monitor setups)

Morten Johan Sørvig Morten Johan Sørvig says:

Thanks for the list! Development and bugfixing is ongoing, and feedback on what the important issues are is helpful.

I’d like to make a small objection to the “shaky” comment though: I would say that the core implementation is solid but that there are a number “leaf” issues that needs to be addressed.

I hope we can do that now after completing the “core” work for 5.6.

Nikita Krupenko says:

I add one more to this list, about QML Canvas:

Daniel says:

By ‘shaky’ I was referring to the way that (a) on retina, Qt apps do not update when the resolution changes (because the user changed it or the app was moved between screens) like native apps and (b) the Windows implementation, at least in Qt 5.4.1 when I tried it, was *entirely* dependant on a integer only environment variable to work. It felt very experimental. Looking at the source code changes, I see that almost all of that has been ripped out in 5.6…

Commenting closed.

Get started today with Qt Download now