QQuickLoader: Check for QQmlEngine before using it
The loader's context may have been removed from the context hierarchy or it may not have a context in the first place. We should not crash then. Pick-to: 5.15 6.2 6.3 Fixes: QTBUG-67950 Change-Id: I1058d5b1f978aa040f8b2f018c4357dd7a3ef333 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
074b66e007
commit
79e885537f
|
@ -1041,9 +1041,15 @@ void QQuickLoaderPrivate::createComponent()
|
|||
const QQmlComponent::CompilationMode mode = asynchronous
|
||||
? QQmlComponent::Asynchronous
|
||||
: QQmlComponent::PreferSynchronous;
|
||||
QQmlContext *context = qmlContext(q);
|
||||
component.setObject(new QQmlComponent(
|
||||
context->engine(), context->resolvedUrl(source), mode, q), q);
|
||||
if (QQmlContext *context = qmlContext(q)) {
|
||||
if (QQmlEngine *engine = context->engine()) {
|
||||
component.setObject(new QQmlComponent(
|
||||
engine, context->resolvedUrl(source), mode, q), q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qmlWarning(q) << "createComponent: Cannot find a QML engine.";
|
||||
}
|
||||
|
||||
#include <moc_qquickloader_p.cpp>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import QtQuick 2
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool a: false
|
||||
property int changes: 0
|
||||
onAChanged: {
|
||||
m.model = 0
|
||||
m.model = 1
|
||||
++changes;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: m
|
||||
model: 1
|
||||
|
||||
Item {
|
||||
Timer {
|
||||
onTriggered: {
|
||||
root.a = true
|
||||
l.source = "loaded.qml"
|
||||
}
|
||||
interval: 0
|
||||
running: true
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: l
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,6 +134,7 @@ private slots:
|
|||
|
||||
void setSourceAndCheckStatus();
|
||||
void asyncLoaderRace();
|
||||
void noEngine();
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QList<QQmlError>)
|
||||
|
@ -1533,6 +1534,20 @@ void tst_QQuickLoader::asyncLoaderRace()
|
|||
QCOMPARE(loader->item(), nullptr);
|
||||
}
|
||||
|
||||
void tst_QQuickLoader::noEngine()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
const QUrl url = testFileUrl("noEngine.qml");
|
||||
QQmlComponent component(&engine, url);
|
||||
QVERIFY2(component.isReady(), qPrintable(component.errorString()));
|
||||
QScopedPointer<QObject> o(component.create());
|
||||
|
||||
const QString message = url.toString()
|
||||
+ QStringLiteral(":27:13: QML Loader: createComponent: Cannot find a QML engine.");
|
||||
QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
|
||||
QTRY_COMPARE(o->property("changes").toInt(), 1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QQuickLoader)
|
||||
|
||||
#include "tst_qquickloader.moc"
|
||||
|
|
Loading…
Reference in New Issue