aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickloader.cpp18
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp69
2 files changed, 87 insertions, 0 deletions
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index d46e25d255..4867e9485a 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -852,6 +852,11 @@ likelihood of glitches in animation. When loading asynchronously the status
will change to Loader.Loading. Once the entire component has been created, the
\l item will be available and the status will change to Loader.Ready.
+Changing the value of this property to \c false while an asynchronous load is in
+progress will force immediate, synchronous completion. This allows beginning an
+asynchronous load and then forcing completion if the Loader content must be
+accessed before the asynchronous load has completed.
+
To avoid seeing the items loading progressively set \c visible appropriately, e.g.
\code
@@ -878,6 +883,19 @@ void QQuickLoader::setAsynchronous(bool a)
return;
d->asynchronous = a;
+
+ if (isComponentComplete() && d->active) {
+ if (d->loadingFromSource && d->component && d->component->isLoading()) {
+ // Force a synchronous component load
+ QUrl currentSource = d->source;
+ d->clear();
+ d->source = currentSource;
+ loadFromSource();
+ } else if (d->incubator && d->incubator->isLoading()) {
+ d->incubator->forceCompletion();
+ }
+ }
+
emit asynchronousChanged();
}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index e72b38e06c..83294b10ab 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -111,6 +111,8 @@ private slots:
void asynchronous();
void asynchronous_clear();
void simultaneousSyncAsync();
+ void asyncToSync1();
+ void asyncToSync2();
void loadedSignal();
void parented();
@@ -1042,6 +1044,73 @@ void tst_QQuickLoader::simultaneousSyncAsync()
delete root;
}
+void tst_QQuickLoader::asyncToSync1()
+{
+ QQmlEngine engine;
+ PeriodicIncubationController *controller = new PeriodicIncubationController;
+ QQmlIncubationController *previous = engine.incubationController();
+ engine.setIncubationController(controller);
+ delete previous;
+
+ QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
+ QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(root);
+
+ QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
+ QVERIFY(loader);
+
+ QVERIFY(!loader->item());
+ root->setProperty("comp", "BigComponent.qml");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ controller->start();
+ QCOMPARE(loader->status(), QQuickLoader::Loading);
+ QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0);
+
+ // force completion before component created
+ loader->setAsynchronous(false);
+ QVERIFY(loader->item());
+ QCOMPARE(loader->progress(), 1.0);
+ QCOMPARE(loader->status(), QQuickLoader::Ready);
+ QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+ delete root;
+}
+
+void tst_QQuickLoader::asyncToSync2()
+{
+ PeriodicIncubationController *controller = new PeriodicIncubationController;
+ QQmlIncubationController *previous = engine.incubationController();
+ engine.setIncubationController(controller);
+ delete previous;
+
+ QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
+ QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(root);
+
+ QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
+ QVERIFY(loader);
+
+ QVERIFY(!loader->item());
+ root->setProperty("comp", "BigComponent.qml");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ controller->start();
+ QCOMPARE(loader->status(), QQuickLoader::Loading);
+ QTRY_COMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+ // force completion after component created but before incubation complete
+ loader->setAsynchronous(false);
+ QVERIFY(loader->item());
+ QCOMPARE(loader->progress(), 1.0);
+ QCOMPARE(loader->status(), QQuickLoader::Ready);
+ QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+ delete root;
+}
+
void tst_QQuickLoader::loadedSignal()
{
PeriodicIncubationController *controller = new PeriodicIncubationController;