aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanthosh Kumar <santhosh.kumar.selvaraj@qt.io>2023-03-06 17:46:38 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-03-10 16:20:46 +0000
commit9c3d0314f08fe1a90e64ce379c9a8c6e21c2f77e (patch)
tree38bbd0d7bcb7eee0177ebcd9c74daf8a38b62ff8
parentaebd77e51b59356f7e41e53d2a02fd647771d2f7 (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.cpp2
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp21
2 files changed, 22 insertions, 1 deletions
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index da04a2956c..fdee5d0b35 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -795,7 +795,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 af7fd237f9..3045f90169 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();
@@ -1495,6 +1496,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;