summaryrefslogtreecommitdiffstats
path: root/src/corelib/animation
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/animation')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp2
-rw-r--r--src/corelib/animation/qanimationgroup.cpp25
-rw-r--r--src/corelib/animation/qanimationgroup_p.h2
-rw-r--r--src/corelib/animation/qsequentialanimationgroup.cpp3
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);