Changing DPI scaling size of display make Qt application's font size get rendered bigger
Asked Answered
O

6

47

I have created some GUI application using Qt. My GUI application contains controls like push button and radio button. When I run the application, buttons and fonts inside button looks normal. When I change the DPI scaling size of display from 100% to 150% or 200%, font size of controls rendered bigger but not control size (pushbutton, radio button) irrespective of resolution. Due to this the text inside controls were cut off. please see the attached image.

Qt application look when DPI scaling size set to 100%

Qt application look when DPI scaling size set to 100%

Qt application look when DPI scaling size set to 200%

Qt application look when DPI scaling size set to 200%

I am running my application in some tablets also. In tablets, DPI scale value should be more than 150% else everything will be shown very small.

I searched in the web for creating UI application in Qt irrespective of resolution and DPI scale value but no luck. So I am posting my questing here. Please let me know if there is some way to get rid of this.

Occipital answered 9/12, 2013 at 6:52 Comment(1)
i have same problem,you have any solution regarding this problem and with out using qt5.6 version,please help meAbles
B
31

High DPI support is enabled from Qt 5.6 onward.

Setting QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling) in your application source code allows automatic high-DPI scaling.

NOTICE: To use the attribute method, you must set the attribute before you create your QApplication object:

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);   
    return app.exec();
}
Bimonthly answered 17/3, 2016 at 11:12 Comment(6)
i have same problem,you have any solution regarding this problem and with out using qt5.6 version,please help meAbles
Thanks for the Notice!Beutler
Perfect answer.Norford
Did this in my Qt 5.8 application - but it did not fix my problems: cms.bgu.tum.de/oip/dpiProblems.pngPoulos
Worked for me, thanks! FYI, I am using QWidgets and not QML.Crackerbarrel
You also have to set environment variable QT_AUTO_SCREEN_SCALE_FACTOR to 1, but there are problems with mouse coordinates if you have 2 monitors, and scaling is set on both, and your window is on the second monitor.Consternate
A
11

Using layouts correctly can help.

http://qt-project.org/doc/qt-4.8/layout.html

Telling the OS that you handle DPI changes, will prevent weird font changes that you weren't expecting.

http://msdn.microsoft.com/en-us/library/ms701681(v=vs.85).aspx

For spacing critical places, you can check the size of your rendered font, and then set the minimum size of your object based on the resulting size of your text.

http://qt-project.org/doc/qt-4.8/qfontmetrics.html#details

https://blog.qt.digia.com/blog/2009/06/26/improving-support-for-higher-dpi-on-vista/

You could try checking with other built in measurements from Qt:

http://qt-project.org/doc/qt-4.8/qpaintdevice.html#widthMM

http://qt-project.org/doc/qt-4.8/qpaintdevice.html#logicalDpiX

If you are using QML, try for pristine layouts of only anchor based placement.

http://qt-project.org/doc/qt-4.8/qml-anchor-layout.html

QApplication has some settings that are somewhat related.

http://qt-project.org/doc/qt-4.8/qapplication.html#setDesktopSettingsAware

You could manually specify the font, too.

http://qt-project.org/doc/qt-4.8/qapplication.html#setFont

Hope that helps.

Always answered 9/12, 2013 at 7:21 Comment(4)
The second link provided by you will work only in Windows right? Is it possible to use that API in QT? Will it work in all other platform?Occipital
Yes, that is a Windows specific one. There may be similar things for other OS's but I am not aware of them.Always
As long as you are compiling for Windows, you can use Windows API calls. Using Window's calls outside of Windows won't compile.Always
i have same problem,you have any solution regarding this problem and with out using qt5.6 version,please help meAbles
B
5

I had a fixed size window which was not large enough to fit all the text it contained when Windows accessibility settings where applied to scale up all text sizes. Windows does this via dpi increases. I fixed this by retreiving the os scaling factor and then adjusted the size of the my window and some of it's layouts (which I couldn't get to scale automatically for some reason).

Here's how I got the dpi scale (in a file called "WindowsDpiScale.h"):

#ifndef WINDOWSDPISCALE_H
#define WINDOWSDPISCALE_H

#include <QtGlobal>

#ifdef Q_OS_WIN

#include <windows.h>

const float DEFAULT_DPI = 96.0;

float windowsDpiScale()
{
    HDC screen = GetDC( 0 );
    FLOAT dpiX = static_cast<FLOAT>( GetDeviceCaps( screen, LOGPIXELSX ) );
    ReleaseDC( 0, screen );
    return dpiX / DEFAULT_DPI;
}

#endif //Q_OS_WIN

#endif // WINDOWSDPISCALE_H

And then, how I applied it in my case:

...
#include "WindowsDpiScale.h"

MainWindow::MainWindow( QWidget *parent )
    : QMainWindow( parent )
{
...
    // Enlarge the window and various child widgets to accomendate
    // OS display scaling (i.e. accessibily options)
    setScaleToOsSettings();
...
}

void MainWindow::setScaleToOsSettings()
{
#ifdef Q_OS_WIN
    setScale( windowsDpiScale() );
#endif
}

void MainWindow::setScale( float scale )
{
    // Resize the window
    this->setFixedSize( (int)(scale * this->maximumWidth()),
                        (int)(scale * this->maximumHeight()) );

    // Resize the layouts within the stacked widget
    foreach( QVBoxLayout * layout,
             windowUi_->pagerStackedWidget->findChildren<QVBoxLayout *>() )
        layout->parentWidget()->setFixedSize(
            (int)(scale * layout->parentWidget()->contentsRect().width()),
            (int)(scale * layout->parentWidget()->contentsRect().height()) );
}
Boneblack answered 2/4, 2015 at 16:15 Comment(3)
Did you try my solution? It is not Qt version dependent. It simply gets the "scaling factor" from Windows. Then it's up to you to resize your widgets based on that - as I show in my example.Boneblack
Is it working on Linux platform? I use Qt on Linux platform.Ables
Please read my answer more carefully. This is a Windows solution I have posted. It could be conceptually applied, however, to any platform. Replace my WindowsDpiScale.h with a file that uses native code in Linux instead to get the dpi and relative scale on that platform.Boneblack
S
4

Here is a workaround:

Create a file qt.conf and add these lines to it.

[Platforms]
WindowsArguments = dpiawareness=0

Put this file in the application binary folder. That's all. It will work well but only issue is that the look will not be that crisp. For delivering it to the customer, add this file where you have your dependency files & while creating setup, like normally you run your dependency files, run this same as well.

Spoilage answered 8/9, 2020 at 9:8 Comment(1)
You might have just once and for all solved the DPI issues that have plagued me for the last couple of years, thank you.Willdon
F
1

There are several options when dealing with high-resolution displays:

  1. Do nothing and develop in high resolution. Eventually, a higher resolution becomes a new standard, everybody will get 13-15-17 inches. It did work in the 2000th, didn't it?
  2. Leave it to the OS. For example, Windows has a special compatibility setting which scales everything to correct size, while keeping the application think that it renders of a low-resolution display. This is called DPI Unaware on Windows.
  3. Try to use Qt capabilities, QT_AUTO_SCREEN_SCALE_FACTOR=0, QT_SCALE_FACTOR=1.
  4. Use a little bit of help from Qt by setting QT_AUTO_SCREEN_SCALE_FACTOR to 1 or a correspondent AA_EnableHighDpiScaling attribute (introduced in Qt 5.6). This will scale widget sizes relative to the font size, so you only need to deal with raster images.
  5. Turn off AA_EnableHighDpiScaling and rethink all your pixel sizes by making them relative to the font size or multiplying them over the device pixel ratio.
  6. An improvement over a previous step: take into an account the device pixel ratio on every display, so that UI is scaled appropriately when you move it to another display.

Sources:

Fully answered 22/7, 2020 at 10:56 Comment(1)
QT_AUTO_SCREEN_SCALE_FACTOR=0 did the trick for me. Thanks.Azalea
T
0

There are many ways.

  • one of them is to have reference (height, width and DPI) and when you run your application on a different setup all you need is to get height, width and the logical dots per inch
  • you can use qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch();

and then you calculate the new font size by multiplying it with the calculated ratio.

qreal refDpi = 216.;
qreal refHeight = 1776.;
qreal refWidth = 1080.;
QRect rect = QGuiApplication::primaryScreen()->geometry();
qreal height = qMax(rect.width(), rect.height());
qreal width = qMin(rect.width(), rect.height());
qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch();
m_ratio = qMin(height/refHeight, width/refWidth);
m_ratioFont = qMin(height*refDpi/(dpi*refHeight), width*refDpi/(dpi*refWidth));
  • the second way, which is extremely simple, more productive and personally I use it, is simply by using stylesheets!!, and the font size won't change by your DPI scaling.

you can use font property like that for example

font: bold italic large "Times New Roman";
Trumantrumann answered 3/6, 2022 at 4:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.