aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-10-23 15:19:09 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-10-23 19:43:32 +0000
commit4d452d5dff2d12a9a44277798f2a70902a3d1891 (patch)
tree3055096e4ac3268ca357f9b9407d9433ccc85f1a
parente04b7c4b7ba2808215825de23cd6d6606cb9102f (diff)
QQuickIconImage: fix crash with image providers
QQuickImageBase::load() cannot call until the component creation is completed, because it requires an associated QML engine. All calls to updateIcon() are guarded with the appropriate isComponentComplete() check, but the sourceSizeChanged() signal was connected directly to updateIcon(). Establish the signal-slot connection at component completion to avoid calling updateIcon() to soon. Task-number: QTBUG-63959 Change-Id: I3c935291796dbae031d2728e1d51c55596a51cd0 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r--src/quickcontrols2/qquickiconimage.cpp3
-rw-r--r--tests/auto/qquickiconimage/data/imageProvider.qml9
-rw-r--r--tests/auto/qquickiconimage/tst_qquickiconimage.cpp39
3 files changed, 49 insertions, 2 deletions
diff --git a/src/quickcontrols2/qquickiconimage.cpp b/src/quickcontrols2/qquickiconimage.cpp
index c628c7ae..885bc7f9 100644
--- a/src/quickcontrols2/qquickiconimage.cpp
+++ b/src/quickcontrols2/qquickiconimage.cpp
@@ -125,9 +125,7 @@ qreal QQuickIconImagePrivate::calculateDevicePixelRatio() const
QQuickIconImage::QQuickIconImage(QQuickItem *parent)
: QQuickImage(*(new QQuickIconImagePrivate), parent)
{
- Q_D(QQuickIconImage);
setFillMode(Pad);
- QObjectPrivate::connect(this, &QQuickImageBase::sourceSizeChanged, d, &QQuickIconImagePrivate::updateIcon);
}
QString QQuickIconImage::name() const
@@ -183,6 +181,7 @@ void QQuickIconImage::componentComplete()
Q_D(QQuickIconImage);
QQuickImage::componentComplete();
d->updateIcon();
+ QObjectPrivate::connect(this, &QQuickImageBase::sourceSizeChanged, d, &QQuickIconImagePrivate::updateIcon);
}
void QQuickIconImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
diff --git a/tests/auto/qquickiconimage/data/imageProvider.qml b/tests/auto/qquickiconimage/data/imageProvider.qml
new file mode 100644
index 00000000..0d7d3033
--- /dev/null
+++ b/tests/auto/qquickiconimage/data/imageProvider.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+import QtQuick.Controls.impl 2.3
+import QtQuick.Templates 2.3 as T
+
+IconLabel {
+ icon.color: "transparent"
+ icon.source: "image://provider/red"
+}
diff --git a/tests/auto/qquickiconimage/tst_qquickiconimage.cpp b/tests/auto/qquickiconimage/tst_qquickiconimage.cpp
index 4e4afb13..77b860a2 100644
--- a/tests/auto/qquickiconimage/tst_qquickiconimage.cpp
+++ b/tests/auto/qquickiconimage/tst_qquickiconimage.cpp
@@ -35,6 +35,7 @@
#include <QtQml/qqmlfileselector.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickimageprovider.h>
#include <QtQuick/qquickitemgrabresult.h>
#include <QtQuick/private/qquickimage_p.h>
#include <QtQuickControls2/private/qquickiconimage_p.h>
@@ -67,6 +68,7 @@ private slots:
void svgSourceBindingSourceSize();
void color();
void fileSelectors();
+ void imageProvider();
private:
void setTheme();
@@ -480,6 +482,43 @@ void tst_qquickiconimage::fileSelectors()
QCOMPARE(iconImageWindowGrab.pixelColor(iconImageWindowGrab.width() / 2, iconImageWindowGrab.height() / 2), QColor(Qt::blue));
}
+class TestImageProvider : public QQuickImageProvider
+{
+public:
+ TestImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) { }
+
+ QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
+ {
+ QSize defaultSize(32, 32);
+ if (size)
+ *size = defaultSize;
+
+ QPixmap pixmap(requestedSize.width() > 0 ? requestedSize.width() : defaultSize.width(),
+ requestedSize.height() > 0 ? requestedSize.height() : defaultSize.height());
+ pixmap.fill(QColor(id).rgba());
+ return pixmap;
+ }
+};
+
+// don't crash (QTBUG-63959)
+void tst_qquickiconimage::imageProvider()
+{
+ QQuickView view;
+ view.engine()->addImageProvider("provider", new TestImageProvider);
+ view.setSource(testFileUrl("imageProvider.qml"));
+ QCOMPARE(view.status(), QQuickView::Ready);
+ view.show();
+ view.requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->findChild<QQuickIconImage *>());
+ QVERIFY(iconImage);
+
+ QImage image = grabItemToImage(iconImage);
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.pixelColor(image.width() / 2, image.height() / 2), QColor(Qt::red));
+}
+
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);