QtQml: Do not evaluate bindings in invalid contexts
If the context is gone, we are technically still able to evaluate QProperty bindings, but we really shouldn't. Pick-to: 6.10 6.9 6.8 6.5 Fixes: QTBUG-137270 Change-Id: I323c26d59788e4b318ec4733e1593e761beb4b6f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
This commit is contained in:
parent
270bd4dc05
commit
ad6d2bc496
|
@ -133,6 +133,9 @@ QUntypedPropertyBinding QQmlPropertyBinding::createFromBoundFunction(const QQmlP
|
|||
|
||||
void QQmlPropertyBindingJS::expressionChanged()
|
||||
{
|
||||
if (!hasValidContext())
|
||||
return;
|
||||
|
||||
auto binding = asBinding();
|
||||
if (!binding->propertyDataPtr)
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {
|
||||
id: outer
|
||||
objectName: "outer"
|
||||
|
||||
property Component c: QtObject {
|
||||
id: inner1
|
||||
objectName: inner2.objectName + "a"
|
||||
}
|
||||
|
||||
property QtObject inner1: c.createObject()
|
||||
|
||||
property QtObject inner2: QtObject {
|
||||
id: inner2
|
||||
objectName: "a"
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@ private slots:
|
|||
void disabledOnReadonlyProperty();
|
||||
void delayed();
|
||||
void bindingOverwriting();
|
||||
void bindingInDeadContext();
|
||||
void bindToQmlComponent();
|
||||
void bindingDoesNoWeirdConversion();
|
||||
void bindNaNToInt();
|
||||
|
@ -500,6 +501,40 @@ void tst_qqmlbinding::bindingOverwriting()
|
|||
QLoggingCategory::setFilterRules(QString());
|
||||
}
|
||||
|
||||
void tst_qqmlbinding::bindingInDeadContext()
|
||||
{
|
||||
// We manually control the deletion order of the objects here.
|
||||
// This is what some of our views also do. One way to prevent
|
||||
// the engine from deleting objects is to parent them to the
|
||||
// application.
|
||||
|
||||
QScopedPointer<QObject> o;
|
||||
QScopedPointer<QObject> inner1;
|
||||
{
|
||||
QScopedPointer<QObject> inner2;
|
||||
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, testFileUrl("bindingInDeadContext.qml"));
|
||||
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
o.reset(c.create());
|
||||
QVERIFY(!o.isNull());
|
||||
o->setParent(QCoreApplication::instance());
|
||||
|
||||
inner1.reset(o->property("inner1").value<QObject *>());
|
||||
QVERIFY(inner1);
|
||||
inner1->setParent(QCoreApplication::instance());
|
||||
|
||||
inner2.reset(o->property("inner2").value<QObject *>());
|
||||
QVERIFY(inner2);
|
||||
inner2->setParent(QCoreApplication::instance());
|
||||
}
|
||||
|
||||
// The objectName binding did not get re-evaluated when inner2 died
|
||||
// because the engine was gone already.
|
||||
QCOMPARE(inner1->objectName(), "aa");
|
||||
}
|
||||
|
||||
void tst_qqmlbinding::bindToQmlComponent()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
|
|
Loading…
Reference in New Issue