From 01ec11507d7ef3de09bad9d1ef8e6d4a3d6c4428 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 10 Oct 2019 14:33:53 +0200 Subject: QStyleSheetStyle: add new property to QPushButton: icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is currently no proper way to change the icon of a pushbutton from css. But there is a need for doing so (QTBUG-2982), and the typical work-around is to instead use the css property 'qproperty-icon'. But setting qproperties from the style is not a good idea in the first place, since it modifies the state of the widget it draws. Moreover, such properties are only set once (in QStyle::polish()), and will not have any effect on pseudo states, like hover. To close this gap, this patch will add a css property 'icon' that can be set on a QPushButton. This property will follow normal css cascading, and respect pseudo states, equal to any other css property. [ChangeLog][QtWidgets][QStyle] You can now set the CSS property 'icon' on a QPushButton to override which icon to draw. Fixes: QTBUG-79137 Change-Id: Ie7e0b0fa4f19471f51108cd4ca931356219d562e Reviewed-by: Christian Ehrlicher Reviewed-by: Jan Arve Sæther --- src/gui/text/qcssparser.cpp | 32 ++++++++++++++++++++++++++++++++ src/gui/text/qcssparser_p.h | 2 ++ 2 files changed, 34 insertions(+) (limited to 'src/gui') diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index ce7c7610c1..793ef5774b 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -123,6 +123,7 @@ static const QCssKnownValue properties[NumProperties - 1] = { { "font-variant", FontVariant }, { "font-weight", FontWeight }, { "height", Height }, + { "icon", QtIcon }, { "image", QtImage }, { "image-position", QtImageAlignment }, { "left", Left }, @@ -1379,6 +1380,37 @@ bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size) return hit; } +bool ValueExtractor::extractIcon(QIcon *icon, QSize *size) +{ + // Find last declaration that specifies an icon + const auto declaration = std::find_if( + declarations.rbegin(), declarations.rend(), + [](const Declaration &decl) { return decl.d->propertyId == QtIcon; }); + if (declaration == declarations.rend()) + return false; + + *icon = declaration->iconValue(); + + // If the value contains a URI, try to get the size of the icon + if (declaration->d->values.isEmpty()) + return true; + + const auto &propertyValue = declaration->d->values.constFirst(); + if (propertyValue.type != Value::Uri) + return true; + + // First try to read just the size from the image without loading it + const QString url(propertyValue.variant.toString()); + QImageReader imageReader(url); + *size = imageReader.size(); + if (!size->isNull()) + return true; + + // Get the size by loading the image instead + *size = imageReader.read().size(); + return true; +} + /////////////////////////////////////////////////////////////////////////////// // Declaration QColor Declaration::colorValue(const QPalette &pal) const diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index ab85e76cf3..b8bf259dda 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -198,6 +198,7 @@ enum Property { QtLineHeightType, FontKerning, QtForegroundTextureCacheKey, + QtIcon, NumProperties }; @@ -855,6 +856,7 @@ struct Q_GUI_EXPORT ValueExtractor bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg); int extractStyleFeatures(); bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size); + bool extractIcon(QIcon *icon, QSize *size); int lengthValue(const Declaration &decl); -- cgit v1.2.3