Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform a smooth downscaling of background images in Qt styles?

Tags:

css

qt

As default, Qt uses a very simple, quick and ugly way of scaling images, Qt::FastTransformation, probably a nearest neighbor interpolation or something very similar.

When dealing with a QPixmap, one can choose a visually better scaling, for example,

pixmap = pixmap.scaledToHeight(height, Qt::SmoothTransformation);

However, what can we do if the image is not in a QPixmap object, but simply a background of a button, or some other widget?

For example, the following is a very simple way of creating an automatically resizing, fully customized button, well suited for a resolution-independent application, when used with layouts and setStretch().

ui->pushButton->setStyleSheet(
    "QPushButton { border-image: url(:/img/button.png) 0 0 0 0 stretch stretch; }"
    "QPushButton:checked { border-image: url(:/img/button_checked.png) 0 0 0 0 stretch stretch; }"
    "QPushButton:pressed { border-image: url(:/img/button_pressed.png) 0 0 0 0 stretch stretch; }"
    "QPushButton:checked:pressed { border-image: url(:/img/button_checked_pressed.png) 0 0 0 0 stretch stretch; }"
    );

I used border-image instead of background-image due to a deficiency in the Qt style sheets.

How can I have a smoother scaling with images used in style sheets?

Implementing the same thing with pixmaps is much less elegant. I'll have to always catch resize events, recompute the new sizes of all my widgets, and repaint them manually.

Edit:

Interestingly, the smooth scaling works with stylesheets if the image is being enlarged, but not when it is shrinked.

In the following example, in the first row, a 32*32 icon is used, and in the second row, a uniform grid larger than 2000*2000.

example

like image 976
vsz Avatar asked Jan 17 '17 06:01

vsz


1 Answers

Internally, Qt uses QPainter to draw the styles, and QPainter uses bilinear interpolation when drawing scaled pixmaps. This has a major drawback from quality perspective when the downscaling factor is small enough, see this bug report for example. For best quality, the background source image should always be within [0.5, 2.0] factor of the target size. AFAICT there is no easy way out of this limitation.

like image 176
arhzu Avatar answered Sep 21 '22 20:09

arhzu