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 Pick-to: 6.2 6.4 6.5 6.5.0 Change-Id: I6c3456cd3bc35a717c139fbd3670c305304f480a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
ab897f8e19
commit
492dc98a28
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue