diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-06-30 13:06:19 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-08-12 15:52:10 +0200 |
commit | f358188cbd2e47f82d7de3612181e628e1f1c05c (patch) | |
tree | 8befff9d83c4e96bab0b2e9af7727238b2e9be87 /tests/auto/qml/qqmlecmascript | |
parent | 26884a4f34cfe6bc10daa19f2096aa49ed0a31f2 (diff) |
Do not set QQmlPropertyBinding until we reach finalize
If we install the binding eagerly, context properties cannot be resolved
yet, as the context object has not been created so far. This causes
issues with a QNotifiedProperty using a callback which accesses the
current value, and thus forcing the binding evaluation while the object
creation is still ongoing.
Change-Id: I3bf3def04cd044371cb757a1854a3224a9c669b8
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmlecmascript')
4 files changed, 47 insertions, 3 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/bindingOnQPropertyContextProperty.qml b/tests/auto/qml/qqmlecmascript/data/bindingOnQPropertyContextProperty.qml new file mode 100644 index 0000000000..85d5f34e69 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/bindingOnQPropertyContextProperty.qml @@ -0,0 +1,17 @@ +import Qt.test 1.0 +import QtQuick 2 + +Item { + id: root + property ClassWithQProperty2 testee: null + Repeater { + model: 2 + Item { + ClassWithQProperty2 { + id: myself + value: index+1 + Component.onCompleted: {if (index == 1) {root.testee = myself}} + } + } + } +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 2059650584..e7f2756ec3 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -456,6 +456,11 @@ void FloatingQObject::componentComplete() Q_ASSERT(!parent()); } +void ClassWithQProperty2::callback() +{ + Q_UNUSED(this->value.value()); // force evaluation +} + void registerTypes() { qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias"); @@ -550,6 +555,7 @@ void registerTypes() qmlRegisterType<ClashingNames>("Qt.test", 1, 0, "ClashingNames"); qmlRegisterType<ClassWithQProperty>("Qt.test", 1, 0, "ClassWithQProperty"); + qmlRegisterType<ClassWithQProperty2>("Qt.test", 1, 0, "ClassWithQProperty2"); } #include "testtypes.moc" diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 514dfb6f8f..725624781b 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1746,6 +1746,15 @@ public slots: void selection(const QItemSelection &is, int n = 0) { funcCalled = QLatin1String("QItemSelection"); } }; +struct ClassWithQProperty2 : public QObject +{ + Q_OBJECT + Q_PROPERTY(float value) +public: + void callback(); + QNotifiedProperty<float, &ClassWithQProperty2::callback> value; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 52b2afe727..deb949e7a5 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -383,6 +383,7 @@ private slots: void semicolonAfterProperty(); void hugeStack(); void bindingOnQProperty(); + void bindingOnQPropertyContextProperty(); void urlConstruction(); void urlPropertyInvalid(); void urlPropertySet(); @@ -9279,17 +9280,28 @@ void tst_qqmlecmascript::bindingOnQProperty() QScopedPointer<QObject> test(component.create()); test->setProperty("externalValue", 42); QCOMPARE(test->property("value").toInt(), 42); - // Value hasn't changed yet... - QCOMPARE(test->property("changeHandlerCount").toInt(), 0); + QCOMPARE(test->property("changeHandlerCount").toInt(), 1); test->setProperty("externalValue", 100); QCOMPARE(test->property("value").toInt(), 100); - QCOMPARE(test->property("changeHandlerCount").toInt(), 1); + QCOMPARE(test->property("changeHandlerCount").toInt(), 2); QVERIFY(qobject_cast<ClassWithQProperty*>(test.data())); QProperty<float> &qprop = static_cast<ClassWithQProperty*>(test.data())->value; QVERIFY(qprop.hasBinding()); } +void tst_qqmlecmascript::bindingOnQPropertyContextProperty() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("bindingOnQPropertyContextProperty.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> test(component.create()); + QVERIFY(!test.isNull()); + auto classWithQProperty = test->property("testee").value<ClassWithQProperty2 *>(); + QVERIFY(classWithQProperty); + QCOMPARE(classWithQProperty->value.value(), 2); +} + void tst_qqmlecmascript::urlConstruction() { QQmlEngine qmlengine; |