diff options
Diffstat (limited to 'src/corelib/animation')
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 2 | ||||
-rw-r--r-- | src/corelib/animation/qanimationgroup.cpp | 25 | ||||
-rw-r--r-- | src/corelib/animation/qanimationgroup_p.h | 2 | ||||
-rw-r--r-- | src/corelib/animation/qsequentialanimationgroup.cpp | 3 |
4 files changed, 30 insertions, 2 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 0be37b7dca..c879eb6d1a 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -1067,6 +1067,8 @@ QAbstractAnimation::~QAbstractAnimation() if (oldState == QAbstractAnimation::Running) QAnimationTimer::unregisterAnimation(this); } + if (d->group) + d->group->removeAnimation(this); } /*! diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index f47d99eb68..ed40817222 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -113,6 +113,11 @@ QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent) */ QAnimationGroup::~QAnimationGroup() { + Q_D(QAnimationGroup); + // We need to clear the animations now while we are still a valid QAnimationGroup. + // If we wait until ~QObject() the QAbstractAnimation's pointer back to us would + // point to a QObject, not a valid QAnimationGroup. + d->clear(true); } /*! @@ -256,7 +261,7 @@ QAbstractAnimation *QAnimationGroup::takeAnimation(int index) void QAnimationGroup::clear() { Q_D(QAnimationGroup); - qDeleteAll(d->animations); + d->clear(false); } /*! @@ -284,6 +289,24 @@ bool QAnimationGroup::event(QEvent *event) return QAbstractAnimation::event(event); } +void QAnimationGroupPrivate::clear(bool onDestruction) +{ + const QList<QAbstractAnimation *> animationsCopy = animations; // taking a copy + animations.clear(); + // Clearing backwards so the indices doesn't change while we remove animations. + for (int i = animationsCopy.count() - 1; i >= 0; --i) { + QAbstractAnimation *animation = animationsCopy.at(i); + animation->setParent(nullptr); + QAbstractAnimationPrivate::get(animation)->group = nullptr; + // If we are in ~QAnimationGroup() it is not safe to called the virtual + // animationRemoved method, which can still be a method in a + // QAnimationGroupPrivate derived class that assumes q_ptr is still + // a valid derived class of QAnimationGroup. + if (!onDestruction) + animationRemoved(i, animation); + delete animation; + } +} void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *) { diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h index 215734b656..4d1d690e69 100644 --- a/src/corelib/animation/qanimationgroup_p.h +++ b/src/corelib/animation/qanimationgroup_p.h @@ -73,6 +73,8 @@ public: virtual void animationInsertedAt(int) { } virtual void animationRemoved(int, QAbstractAnimation *); + void clear(bool onDestruction); + void disconnectUncontrolledAnimation(QAbstractAnimation *anim) { //0 for the signal here because we might be called from the animation destructor diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index 150e74d7d6..66e346a2fe 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -532,7 +532,8 @@ void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnim Q_Q(QSequentialAnimationGroup); QAnimationGroupPrivate::animationRemoved(index, anim); - Q_ASSERT(currentAnimation); // currentAnimation should always be set + if (!currentAnimation) + return; if (actualDuration.size() > index) actualDuration.removeAt(index); |