diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-09-22 10:48:23 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-10-12 17:50:07 +0200 |
commit | a243f1eeeb9eda237ea2f6dad403984ab14aa375 (patch) | |
tree | 3ded380bfe0f1293263403d2676a3e3db0709160 /tests | |
parent | 7750609d8850f6b36317b6243db77b3fe98fd841 (diff) |
Fix QProperty property interaction with aliases
With this change, an alias of a bindable property is also bindable, and
shares its bindable interface with the target.
Moreover, the logic in QQmlTypeCompiler is adjusted so that a change
handler of an alias uses the bindable interface if possible, instead of
connecting to the alias' change signal. That would never be emitted if
the target is a QProperty without a notify signal.
Alias properties still have a change signal, but those never get
emitted.
Change-Id: I857dfdbe51048a2b604ad632982e7f4adac6b907
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml | 7 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 37 |
2 files changed, 44 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml b/tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml new file mode 100644 index 0000000000..6c37a33f39 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/aliasOfQProperty.qml @@ -0,0 +1,7 @@ +import Qt.test 1.0 +ClassWithQProperty { + id: root + property alias myAlias: root.value + property int changeCounter: 0 + onMyAliasChanged: ++changeCounter +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index ef2eb5ad03..e3396a430f 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -382,6 +382,7 @@ private slots: void semicolonAfterProperty(); void hugeStack(); void bindingOnQProperty(); + void aliasOfQProperty(); void bindingOnQPropertyContextProperty(); void bindingContainingQProperty(); void urlConstruction(); @@ -9177,6 +9178,42 @@ void tst_qqmlecmascript::bindingOnQProperty() QVERIFY(qprop.hasBinding()); } +void tst_qqmlecmascript::aliasOfQProperty() { + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("aliasOfQProperty.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> root(component.create()); + QProperty<float> &qprop = static_cast<ClassWithQProperty*>(root.data())->value; + QProperty<float> otherProperty; + + + qprop.setBinding([&](){return otherProperty.value();}); + // changing the target properties value triggers the alias property's change handler exactly + // once, and doesn't require reading the value (binding is no longer lazy) + otherProperty.setValue(42.0); + QCOMPARE(root->property("changeCounter").toInt(), 1); + // reading the value afterwards doesn't trigger the observer again + QCOMPARE(root->property("myAlias").toFloat(), 42.0); + QCOMPARE(root->property("changeCounter").toInt(), 1); + + // writing to the alias breaks the binding + root->setProperty("myAlias", 12.0); + QCOMPARE(qprop.value(), 12.0); + QVERIFY(!qprop.hasBinding()); + + // it is possible to obtain the bindable interface of the target from the bindable property + QUntypedBindable bindable; + void *argv[] = { &bindable }; + int myaliasPropertyIndex = root->metaObject()->indexOfProperty("myAlias"); + root->metaObject()->metacall(root.get(), QMetaObject::BindableProperty, myaliasPropertyIndex, argv); + QVERIFY(bindable.isValid()); + + bool ok = bindable.setBinding(Qt::makePropertyBinding([&]() -> float {return 13.0; } )); + QVERIFY(ok); + QVERIFY(qprop.hasBinding()); + QCOMPARE(qprop.value(), 13.0); +} + void tst_qqmlecmascript::bindingOnQPropertyContextProperty() { QSKIP("Test needs to be adjusted"); |