From c63c918f3a448436a4279abc0775b97d996f09a7 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 19 Mar 2025 20:32:56 +0100 Subject: [PATCH] QLabel: don't cache scaled pixmap in QIcon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caching the scaled QPixmap directly in QIcon is not a good idea - the cached pixmap might be used as starting point for a pixmap with another size so it gets blurry - QIcon has no caching mechanism to throw away unneeded QPixmaps after some time so the memory usage grows indefinitely Fixes: QTBUG-134930 Change-Id: Ic490ba15438a5cd07a555692e1d08cd1c211d005 Reviewed-by: Volker Hilsheimer (cherry picked from commit 7a238e1225f49b81772516ed5d0a5a4f4f2e9268) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 04cb0a1b55cc3c2b402d22f9f7a76b726407dc71) Reviewed-by: Topi Reiniƶ --- src/widgets/widgets/qlabel.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index b0e0d417610..5ddd2fbb5a9 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -6,6 +6,7 @@ #include "qstyle.h" #include "qstyleoption.h" #include "qlabel_p.h" +#include "private/qhexstring_p.h" #include "private/qstylesheetstyle_p.h" #include @@ -1054,9 +1055,21 @@ void QLabel::paintEvent(QPaintEvent *) const auto mode = isEnabled() ? QIcon::Normal : QIcon::Disabled; QPixmap pix = d->icon->pixmap(size, dpr, mode); if (d->scaledcontents && pix.size() != size * dpr) { - pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - pix.setDevicePixelRatio(dpr); - d->icon->addPixmap(pix, mode); + const QString key = "qt_label_"_L1 % HexString(pix.cacheKey()) + % HexString(mode) + % HexString(size.width()) + % HexString(size.height()) + % HexString(qRound(dpr * 1000)); + if (!QPixmapCache::find(key, &pix)) { + pix = pix.scaled(size * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + pix.setDevicePixelRatio(dpr); + // using QIcon to cache the newly create pixmap is not possible + // because QIcon does not clear this cache (so we grow indefinitely) + // and also uses the newly added pixmap as starting point for new + // scaled pixmap which makes it very blurry. + // Therefore use QPixmapCache here. + QPixmapCache::insert(key, pix); + } } QStyleOption opt; opt.initFrom(this);