diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index be2bed0a07..03efb7f691 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -91,7 +91,7 @@ QT_BEGIN_NAMESPACE void QPropertyAnimationPrivate::updateMetaProperty() { - if (!target || propertyName.isEmpty()) { + if (!target || propertyName.value().isEmpty()) { propertyType = QMetaType::UnknownType; propertyIndex = -1; return; @@ -99,8 +99,8 @@ void QPropertyAnimationPrivate::updateMetaProperty() //propertyType will be set to a valid type only if there is a Q_PROPERTY //otherwise it will be set to QVariant::Invalid at the end of this function - propertyType = targetValue->property(propertyName).userType(); - propertyIndex = targetValue->metaObject()->indexOfProperty(propertyName); + propertyType = targetValue->property(propertyName.value()).userType(); + propertyIndex = targetValue->metaObject()->indexOfProperty(propertyName.value()); if (propertyType != QMetaType::UnknownType) convertValues(propertyType); @@ -108,9 +108,13 @@ void QPropertyAnimationPrivate::updateMetaProperty() //there is no Q_PROPERTY on the object propertyType = QMetaType::UnknownType; if (!targetValue->dynamicPropertyNames().contains(propertyName)) - qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData()); + qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of " + "your QObject", + propertyName.value().constData()); } else if (!targetValue->metaObject()->property(propertyIndex).isWritable()) { - qWarning("QPropertyAnimation: you're trying to animate the non-writable property %s of your QObject", propertyName.constData()); + qWarning("QPropertyAnimation: you're trying to animate the non-writable property %s of " + "your QObject", + propertyName.value().constData()); } } @@ -132,7 +136,7 @@ void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue) void *argv[] = { const_cast(newValue.constData()), const_cast(&newValue), &status, &flags }; QMetaObject::metacall(targetValue, QMetaObject::WriteProperty, propertyIndex, argv); } else { - targetValue->setProperty(propertyName.constData(), newValue); + targetValue->setProperty(propertyName.value().constData(), newValue); } } @@ -214,10 +218,20 @@ void QPropertyAnimation::setPropertyName(const QByteArray &propertyName) return; } - d->propertyName = propertyName; + d->propertyName.removeBindingUnlessInWrapper(); + + if (d->propertyName == propertyName) + return; + + d->propertyName.setValueBypassingBindings(propertyName); d->updateMetaProperty(); + d->propertyName.notify(); } +QBindable QPropertyAnimation::bindablePropertyName() +{ + return &d_func()->propertyName; +} /*! \reimp @@ -252,8 +266,9 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState, Q_D(QPropertyAnimation); if (!d->target && oldState == Stopped) { - qWarning("QPropertyAnimation::updateState (%s): Changing state of an animation without target", - d->propertyName.constData()); + qWarning("QPropertyAnimation::updateState (%s): Changing state of an animation without " + "target", + d->propertyName.value().constData()); return; } @@ -276,7 +291,8 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState, locker.unlock(); // update the default start value if (oldState == Stopped) { - d->setDefaultStartEndValue(d->targetValue->property(d->propertyName.constData())); + d->setDefaultStartEndValue( + d->targetValue->property(d->propertyName.value().constData())); //let's check if we have a start value and an end value const char *what = nullptr; if (!startValue().isValid() && (d->direction == Backward || !d->defaultStartEndValue.isValid())) { @@ -289,8 +305,10 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState, what = "end"; } if (Q_UNLIKELY(what)) { - qWarning("QPropertyAnimation::updateState (%s, %s, %ls): starting an animation without %s value", - d->propertyName.constData(), d->target.data()->metaObject()->className(), + qWarning("QPropertyAnimation::updateState (%s, %s, %ls): starting an animation " + "without %s value", + d->propertyName.value().constData(), + d->target.data()->metaObject()->className(), qUtf16Printable(d->target.data()->objectName()), what); } } diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index a1caafcad5..4482e7f7ab 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -50,7 +50,8 @@ class QPropertyAnimationPrivate; class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation { Q_OBJECT - Q_PROPERTY(QByteArray propertyName READ propertyName WRITE setPropertyName) + Q_PROPERTY(QByteArray propertyName READ propertyName WRITE setPropertyName BINDABLE + bindablePropertyName) Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject) public: @@ -63,6 +64,7 @@ public: QByteArray propertyName() const; void setPropertyName(const QByteArray &propertyName); + QBindable bindablePropertyName(); protected: bool event(QEvent *event) override; diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index cbd3ce287d..0b1bb2bd03 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -54,6 +54,7 @@ #include "qpropertyanimation.h" #include "private/qvariantanimation_p.h" +#include "private/qproperty_p.h" QT_REQUIRE_CONFIG(animation); @@ -76,7 +77,12 @@ public: int propertyType; int propertyIndex; - QByteArray propertyName; + void setPropertyName(const QByteArray &propertyName) + { + q_func()->setPropertyName(propertyName); + } + Q_OBJECT_COMPAT_PROPERTY(QPropertyAnimationPrivate, QByteArray, propertyName, + &QPropertyAnimationPrivate::setPropertyName) void updateProperty(const QVariant &); void updateMetaProperty(); }; diff --git a/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt b/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt index 5233616115..89a4d0a8e1 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt +++ b/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt @@ -11,4 +11,6 @@ qt_internal_add_test(tst_qpropertyanimation Qt::CorePrivate Qt::Gui Qt::Widgets + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp index 2c7587c2fe..5286daec6a 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -193,6 +194,7 @@ private slots: void totalDuration(); void zeroLoopCount(); void recursiveAnimations(); + void bindings(); }; void tst_QPropertyAnimation::initTestCase() @@ -1399,6 +1401,14 @@ void tst_QPropertyAnimation::recursiveAnimations() QCOMPARE(o.y(), qreal(4000)); } +void tst_QPropertyAnimation::bindings() +{ + AnimationObject o; + QPropertyAnimation a(&o, "value"); + + QTestPrivate::testReadWritePropertyBasics(a, QByteArray("value"), QByteArray("realValue"), + "propertyName"); +} QTEST_MAIN(tst_QPropertyAnimation) #include "tst_qpropertyanimation.moc"