diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-08-29 15:46:20 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-08-30 22:48:45 +0000 |
commit | 0f1b671738954c3db8394aa9d189402377a7dfbd (patch) | |
tree | 75327759ed1d6111f28854156613ee1d491dac28 | |
parent | 3f2cf8520d989fd57fc4918099ba43167033722a (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.cpp | 15 | ||||
-rw-r--r-- | tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml | 23 | ||||
-rw-r--r-- | tests/auto/quick/qquickstates/tst_qquickstates.cpp | 21 |
3 files changed, 54 insertions, 5 deletions
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 6784ad83d6..854b7d83d7 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -140,8 +140,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(); @@ -194,8 +196,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); } @@ -262,7 +266,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 d6814bd057..35d6deee58 100644 --- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp +++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp @@ -207,6 +207,7 @@ private slots: void parentChangeInvolvingBindings(); void deferredProperties(); void rewindAnchorChange(); + void bindingProperlyRemovedWithTransition(); }; void tst_qquickstates::initTestCase() @@ -1978,6 +1979,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" |