Wizards: Accept asynchronous root components for qtquickapplication

There are a number of reasons why the root component of a QtQuick
application may be loaded asynchronously. It might, for example, be
derived from a component loaded over the network.

In that case, checking that there is a root object right after calling
load() is misleading. The object is only created later. Therefore, we
need to listen for the objectCreated signal to decide if the root
component was correctly created.

As calling qApp->exit(-1) does nothing while the event loop isn't
running, we always connect the check with Qt::QueuedConnection.

Change-Id: Ie2814894b79bb3e467c5a838c7ec419291fcf591
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
Ulf Hermann
2017-09-29 15:56:36 +02:00
parent cd89951973
commit dcb8681cb7

View File

@@ -16,9 +16,25 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
const QUrl mainQml(QStringLiteral("qrc:/main.qml"));
// Catch the objectCreated signal, so that we can determine if the root component was loaded
// successfully. If not, then the object created from it will be null. The root component may
// get loaded asynchronously.
const QMetaObject::Connection connection = QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated,
&app, [&](QObject *object, const QUrl &url) {
if (url != mainQml)
return;
if (!object)
app.exit(-1);
else
QObject::disconnect(connection);
}, Qt::QueuedConnection);
engine.load(mainQml);
return app.exec();
}