diff options
author | Santhosh Kumar <santhosh.kumar.selvaraj@qt.io> | 2023-03-06 17:46:38 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-03-10 15:27:38 +0000 |
commit | 8bcafe245f9d32edce41a53741b820a854ea452b (patch) | |
tree | 888e91d00e19f1d0c9866b30ecf8ac01721d55ae | |
parent | 2cac1965835588b9090fbef18dab62bc6a15f949 (diff) |
Fix multiple object creation in Loader
QML Loader creates multiple object of same component during initial
loading, if sourceComponent is assigned within state configuration
and it evaluates to be true. This happens due to the effect of
evaluating stage change (here in this case, setting loader source
component) during component completion which internally creates
component object and makes loader status be ready, even before
Loader instantiates object.
This patch adds a guard to check loader status and avoids object
creation if status is already ready.
Fixes: QTBUG-111559
Change-Id: I6c3456cd3bc35a717c139fbd3670c305304f480a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 492dc98a288763d3d026e9557ffadc018cede350)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quick/items/qquickloader.cpp | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickloader/tst_qquickloader.cpp | 21 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 7bb21a6d9d..d33e06a273 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -768,7 +768,7 @@ void QQuickLoader::componentComplete() { Q_D(QQuickLoader); QQuickItem::componentComplete(); - if (active()) { + if (active() && (status() != Ready)) { if (d->loadingFromSource) d->createComponent(); d->load(); diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 7562dd1672..94fca41a02 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -108,6 +108,7 @@ private slots: void statusChangeOnlyEmittedOnce(); void setSourceAndCheckStatus(); + void loadComponentWithStates(); void asyncLoaderRace(); void noEngine(); @@ -1493,6 +1494,26 @@ void tst_QQuickLoader::setSourceAndCheckStatus() QCOMPARE(loader->status(), QQuickLoader::Null); } +void tst_QQuickLoader::loadComponentWithStates() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QByteArray("import QtQuick\n" + "Loader {\n" + "id: loader\n" + "property int createdObjCount: 0\n" + "states: [ State { when: true; PropertyChanges { target: loader; sourceComponent: myComp } } ]\n" + "Component { id: myComp; Item { Component.onCompleted: { ++createdObjCount } } }\n" + "}" ) + , dataDirectoryUrl()); + QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create())); + QTest::qWait(200); + QTRY_VERIFY(loader != nullptr); + QVERIFY(loader->item()); + QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().size(), 1); + QCOMPARE(loader->property("createdObjCount").toInt(), 1); +} + void tst_QQuickLoader::asyncLoaderRace() { QQmlApplicationEngine engine; |