70void QPropertyAnimationPrivate::updateMetaProperty()
72 const QObject *target = targetObject.valueBypassingBindings();
73 if (!target || propertyName.value().isEmpty()) {
74 propertyType = QMetaType::UnknownType;
81 propertyType = target->property(propertyName.value()).userType();
82 propertyIndex = target->metaObject()->indexOfProperty(propertyName.value());
84 if (propertyType != QMetaType::UnknownType)
85 convertValues(propertyType);
86 if (propertyIndex == -1) {
88 propertyType = QMetaType::UnknownType;
89 if (!target->dynamicPropertyNames().contains(propertyName))
90 qWarning(
"QPropertyAnimation: you're trying to animate a non-existing property %s of "
92 propertyName.value().constData());
93 }
else if (!target->metaObject()->property(propertyIndex).isWritable()) {
94 qWarning(
"QPropertyAnimation: you're trying to animate the non-writable property %s of "
96 propertyName.value().constData());
113 void *argv[] = {
const_cast<
void *>(newValue.constData()),
const_cast<QVariant *>(&newValue), &status, &flags };
114 QMetaObject::metacall(targetObject, QMetaObject::WriteProperty, propertyIndex, argv);
136QPropertyAnimation::QPropertyAnimation(QObject *target,
const QByteArray &propertyName, QObject *parent)
137 : QVariantAnimation(*
new QPropertyAnimationPrivate, parent)
139 setTargetObject(target);
140 setPropertyName(propertyName);
167void QPropertyAnimation::setTargetObject(QObject *target)
169 Q_D(QPropertyAnimation);
170 if (d->state != QAbstractAnimation::Stopped) {
171 qWarning(
"QPropertyAnimation::setTargetObject: you can't change the target of a running animation");
175 d->targetObject.removeBindingUnlessInWrapper();
176 const QObject *oldTarget = d->targetObject.valueBypassingBindings();
177 if (oldTarget == target)
180 if (oldTarget !=
nullptr)
181 QObject::disconnect(oldTarget, &QObject::destroyed,
this,
nullptr);
182 d->targetObject.setValueBypassingBindings(target);
184 if (target !=
nullptr) {
185 QObject::connect(target, &QObject::destroyed,
this,
186 [d] { d->targetObjectDestroyed(); });
188 d->updateMetaProperty();
189 d->targetObject.notify();
205void QPropertyAnimation::setPropertyName(
const QByteArray &propertyName)
207 Q_D(QPropertyAnimation);
208 if (d->state != QAbstractAnimation::Stopped) {
209 qWarning(
"QPropertyAnimation::setPropertyName: you can't change the property name of a running animation");
213 d->propertyName.removeBindingUnlessInWrapper();
215 if (d->propertyName.valueBypassingBindings() == propertyName)
218 d->propertyName.setValueBypassingBindings(propertyName);
219 d->updateMetaProperty();
220 d->propertyName.notify();
255void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
256 QAbstractAnimation::State oldState)
258 Q_D(QPropertyAnimation);
260 if (!d->targetObject && oldState == Stopped) {
261 qWarning(
"QPropertyAnimation::updateState (%s): Changing state of an animation without "
263 d->propertyName.value().constData());
267 QVariantAnimation::updateState(newState, oldState);
269 QPropertyAnimation *animToStop =
nullptr;
271 Q_CONSTINIT
static QBasicMutex mutex;
272 auto locker = qt_unique_lock(mutex);
273 using QPropertyAnimationPair = std::pair<QObject *, QByteArray>;
274 typedef QHash<QPropertyAnimationPair, QPropertyAnimation*> QPropertyAnimationHash;
275 Q_CONSTINIT
static QPropertyAnimationHash hash;
283 Q_ASSERT(d->targetObject);
285 QPropertyAnimationPair key(d->targetObject, d->propertyName);
286 if (newState == Running) {
287 d->updateMetaProperty();
288 animToStop = hash.value(key,
nullptr);
289 hash.insert(key,
this);
292 if (oldState == Stopped) {
293 d->setDefaultStartEndValue(
294 d->targetObject->property(d->propertyName.value().constData()));
296 const char *what =
nullptr;
297 if (!startValue().isValid() && (d->direction == Backward || !d->defaultStartEndValue.isValid())) {
300 if (!endValue().isValid() && (d->direction == Forward || !d->defaultStartEndValue.isValid())) {
302 what =
"start and end";
306 if (Q_UNLIKELY(what)) {
307 qWarning(
"QPropertyAnimation::updateState (%s, %s, %ls): starting an animation "
309 d->propertyName.value().constData(),
310 d->targetObject->metaObject()->className(),
311 qUtf16Printable(d->targetObject->objectName()), what);
314 }
else if (hash.value(key) ==
this) {
322 QAbstractAnimation *current = animToStop;
323 while (current->group() && current->state() != Stopped)
324 current = current->group();