Binding: fix restore logic
Consider a Binding affecting a property which initially has a value (not a binding). When restoring the initial value of a property, we did not remove any binding that might have been installed on it by Binding. Then, when the Binding would subsequently get enabled again, it would pick up the still installed binding instead of the actually restored property. From that point on, the original value would have been lost. Fix this by clearing any existing bindings when we restore a value. Pick-to: 6.7 6.6 6.5 Fixes: QTBUG-122707 Change-Id: Ife7c43c7e799c71257fc04bbd76ff902422bd49d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
27c25c8ddc
commit
98ecc9adbb
|
@ -1029,6 +1029,7 @@ void QQmlBind::eval()
|
|||
break;
|
||||
case QQmlBindEntryKind::V4Value:
|
||||
if (d->restoreValue) {
|
||||
QQmlAnyBinding::takeFrom(entry.prop); // we don't want to have a binding active
|
||||
auto propPriv = QQmlPropertyPrivate::get(entry.prop);
|
||||
QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(propPriv->object);
|
||||
Q_ASSERT(vmemo);
|
||||
|
@ -1039,6 +1040,7 @@ void QQmlBind::eval()
|
|||
break;
|
||||
case QQmlBindEntryKind::Variant:
|
||||
if (d->restoreValue) {
|
||||
QQmlAnyBinding::takeFrom(entry.prop); // we don't want to have a binding active
|
||||
entry.prop.write(entry.previous.variant);
|
||||
entry.clearPrev();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
property bool enabled: false
|
||||
property var func: function() { return 1 }
|
||||
property var arr: [1, 2]
|
||||
property Binding b: Binding {
|
||||
root.func: function() { return 2 };
|
||||
root.arr: [1, 2, 3]
|
||||
when: root.enabled
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ private slots:
|
|||
void localSignalHandler();
|
||||
void whenEvaluatedEarlyEnough();
|
||||
void propertiesAttachedToBindingItself();
|
||||
void toggleEnableProperlyRemembersValues();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -625,6 +626,30 @@ void tst_qqmlbinding::propertiesAttachedToBindingItself()
|
|||
QTRY_COMPARE(root->property("check").toInt(), 3);
|
||||
}
|
||||
|
||||
void tst_qqmlbinding::toggleEnableProperlyRemembersValues()
|
||||
{
|
||||
QQmlEngine e;
|
||||
QQmlComponent c(&e, testFileUrl("toggleEnableProperlyRemembersValues.qml"));
|
||||
std::unique_ptr<QObject> root { c.create() };
|
||||
QVERIFY2(root, qPrintable(c.errorString()));
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
{
|
||||
QJSManagedValue arr(root->property("arr"), &e);
|
||||
QJSManagedValue func(root->property("func"), &e);
|
||||
QCOMPARE(arr.property("length").toInt(), 2);
|
||||
QCOMPARE(func.call().toInt(), 1);
|
||||
}
|
||||
root->setProperty("enabled", true);
|
||||
{
|
||||
QJSManagedValue arr(root->property("arr"), &e);
|
||||
QJSManagedValue func(root->property("func"), &e);
|
||||
QCOMPARE(arr.property("length").toInt(), 3);
|
||||
QCOMPARE(func.call().toInt(), 2);
|
||||
}
|
||||
root->setProperty("enabled", false);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmlbinding)
|
||||
|
||||
#include "tst_qqmlbinding.moc"
|
||||
|
|
Loading…
Reference in New Issue