aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2022-08-29 15:46:20 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-08-30 22:48:44 +0000
commit422c6a23ad85d76efa1e8ddee658759cda44672f (patch)
treea31ee598c4dd682c66fb8e3a03f76f942fdec9d0
parent2b42c90c3773d3479a9b7d8452087828189573e9 (diff)
Transition: properly remove QPropery based bindings
We need to use QQmlAnyBinding::removeBindingFrom instead of the functionality in QQmlPropertyPrivate, as the latter does not correctly handle QProperty based bindings. Fixes: QTBUG-105535 Change-Id: Ifcd8d3a97ff6d62b365008768e6bf50cfa102a39 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit af5f853413c633c665696dc176677fdde196dd01) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp15
-rw-r--r--tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml23
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp21
3 files changed, 54 insertions, 5 deletions
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp
index 53aa6608aa..1862aa0fc8 100644
--- a/src/quick/util/qquicktransitionmanager.cpp
+++ b/src/quick/util/qquicktransitionmanager.cpp
@@ -104,8 +104,10 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
for (const QQuickStateAction &action : qAsConst(applyList)) {
if (action.toBinding)
d->bindingsList << action;
- if (action.fromBinding)
- QQmlPropertyPrivate::removeBinding(action.property); // Disable current binding
+ if (action.fromBinding) {
+ auto property = action.property;
+ QQmlAnyBinding::removeBindingFrom(property); // Disable current binding
+ }
if (action.event && action.event->changesBindings()) { //### assume isReversable()?
d->bindingsList << action;
action.event->clearBindings();
@@ -158,8 +160,10 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
continue;
}
- if (action.toBinding)
- QQmlPropertyPrivate::removeBinding(action.property); // Make sure this is disabled during the transition
+ if (action.toBinding) {
+ auto property = action.property;
+ QQmlAnyBinding::removeBindingFrom(property); // Make sure this is disabled during the transition
+ }
QQmlPropertyPrivate::write(action.property, action.fromValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
}
@@ -226,7 +230,8 @@ void QQuickTransitionManager::cancel()
for (const QQuickStateAction &action : qAsConst(d->bindingsList)) {
if (action.toBinding && action.deletableToBinding) {
- QQmlPropertyPrivate::removeBinding(action.property);
+ auto property = action.property;
+ QQmlAnyBinding::removeBindingFrom(property);
} else if (action.event) {
//### what do we do here?
}
diff --git a/tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml b/tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml
new file mode 100644
index 0000000000..ed40e18374
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml
@@ -0,0 +1,23 @@
+import QtQuick
+
+Item {
+ id: root
+ property bool toggle: true
+ property int state1Width: 500
+
+ states: [
+ State {
+ when: root.toggle
+ PropertyChanges { root.width: root.state1Width }
+ },
+ State {
+ when: !root.toggle
+ PropertyChanges { root.width: 300 }
+ }
+ ]
+
+ transitions: Transition {
+ id: transition
+ SmoothedAnimation { target: root; property: "width"; velocity: 200 }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index a57f186d80..6aceaf9827 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -183,6 +183,7 @@ private slots:
void parentChangeInvolvingBindings();
void deferredProperties();
void rewindAnchorChange();
+ void bindingProperlyRemovedWithTransition();
};
void tst_qquickstates::initTestCase()
@@ -1964,6 +1965,26 @@ void tst_qquickstates::rewindAnchorChange()
QTRY_COMPARE(innerRect->height(), 200);
}
+void tst_qquickstates::bindingProperlyRemovedWithTransition()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("removeBindingWithTransition.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> root(c.create());
+ QVERIFY(root);
+ QQuickItem *item = qobject_cast<QQuickItem *>(root.get());
+ QVERIFY(item);
+
+ item->setProperty("toggle", false);
+ QTRY_COMPARE(item->width(), 300);
+
+ item->setProperty("state1Width", 100);
+ QCOMPARE(item->width(), 300);
+
+ item->setProperty("toggle", true);
+ QTRY_COMPARE(item->width(), 100);
+}
+
QTEST_MAIN(tst_qquickstates)
#include "tst_qquickstates.moc"