I load QPixmap
objects from a png
files embedded in a qrc
file and scale them to 16x16. I use those pixmaps to draw on QTableView
cells or in QtItem::DecorationRole
from various models. The overall look was fine on windows 10 but when I tried on windows 11 the images displayed were blured and not clear and it turned out the windows scaling is the cause. I set the scaling factor in Display Settings
to 125% because it was recommended by windows and a factor of 100% looked too small compared to windows 10. When the scale factor is increased Qt
automatically detects this and scale all draw objects including texts and images, but texts are still clear unlink displayed images which become unclear. I think it is because the pixmap was resized to 16x16 and when it is scaled for larger than 100% the quality of the image drops like when zooming a small image, but how can I make QPixmap
work across different scaling factors? Should I keep the original size and resize in demands when panting?
I currently use Qt 6.4.1 downloaded with qt online installer.
Previously I used Qt 5.12 built from sources on Windows 10 but when the application runs on windows 11 it doesn't respect the scaling factor of windows
CodePudding user response:
To simplify, you can start doing the following:
Get the current device pixel ratio (DPR) using
QScreen::devicePixelRatio
.If the architecture allows you to have multiple device pixel ratio (Windows 10 and macOS do), you may want to check the screen where your pixmap will be displayed using
QGuiApplication::screenAt
(Qt 6), orQDesktopWidget::screenNumber
(Qt 5).Set the pixmap's DPR to the one got above.
Scale your bitmap accordingly: actual_size = desired_size * DPR. So, if your DPR is 1.25 (125%) and you want the pixmap to be 100x100, then scale it to 125x125.
You can store all these pixmaps in a single QIcon
for easier handing (as commented above).
Take into consideration that in systems with multiple DPR, you may need to keep track of screen changes and update the pixmap. Here some ideas:
Listen at
QWindow::screenChanged
to detect a change in the window. If not a window, you can checkQWidget::moveEvent
.Listen at
QGuiApplication::screenRemoved
to detect when the user has removed a screen and check if your widget was there (in this case it will be moved to the primary screen).
In addition, remember to configure your application to support HiDPI:
- Set
Qt::AA_EnableHighDpiScaling
application attribute. This is required only in Qt 5; Qt 6 enables it by default. - Check the HiDPI rounding policy (default value varies between Qt 5 and Qt 6).