Das Animations-Framework
Das Animations-Framework bietet eine einfache Möglichkeit, Ihre GUI-Elemente zu animieren. Es ermöglicht Ihnen, den Wert einer Qt-Eigenschaft eines Widgets oder QObject zu animieren. Die meisten Funktionen des Frameworks sind auch in Qt Quickverfügbar, wo es möglich ist, Animationen auf deklarative Weise zu definieren.
In diesem Überblick wird die Architektur des Frameworks anhand von Beispielen erläutert, die die gängigen Techniken zur Animation von QObject und GUI-Elementen demonstrieren.
Die Architektur der Animation
Das folgende Diagramm zeigt die wichtigsten Klassen, die das Framework zur Verfügung stellt:
Es enthält die Klasse QAbstractAnimation, die die notwendige Grundlage für Animationen bietet. Diese Klasse definiert die generischen Eigenschaften für alle vom Framework unterstützten Animationen. Zum Beispiel die Fähigkeit, eine Animation zu starten, zu stoppen und zu pausieren. Die Klasse empfängt auch die Benachrichtigungen über Zeitänderungen.
Das Framework bietet außerdem die Klassen QVariantAnimation und QAnimationGroup, die auf ihrem Basisfall QAbstractAnimation aufbauen. Die nächste Klasse in der Hierarchie ist QPropertyAnimation, die von QVariantAnmiation abgeleitet ist und mit der Sie eine Qt-Eigenschaft eines Widgets oder QObject animieren können. Die Klasse führt eine Interpolation des Eigenschaftswerts mithilfe einer Entspannungskurve durch. Damit benötigen Sie lediglich eine QObject Klasse mit einem Qt-Eigenschaftswert, den Sie animieren können.
Hinweis: Es ist erforderlich, dass das Zielobjekt, das Sie animieren, eine QObject oder deren Unterklasse ist. Dies ist notwendig, da das Animations-Framework auf das Meta-Objekt-System angewiesen ist, um alle Informationen über das zu animierende Objekt zu erhalten.
Komplexe Animationen können durch den Aufbau einer Baumstruktur von QAbstractAnimationerstellt werden, wobei der Baum eine QAnimationGroup ist, die andere Animationen enthält. Diese Animationsgruppen können auch Untergruppen enthalten, die verschiedene Gruppen oder Animationen repräsentieren, wie z. B. QParallelAnimationGroup und QSequentialAnimationGroup.
Hinter den Kulissen werden alle Animationen von einem globalen Timer gesteuert, der updates über alle laufenden Animationen informiert.
Detaillierte Informationen zu den einzelnen Klassen und ihrer Rolle im Framework finden Sie in der jeweiligen Dokumentation.
Vom Framework angebotene Klassen
Diese Klassen bieten die notwendige Infrastruktur, um sowohl einfache als auch komplexe Animationen zu erstellen.
Die Basis für alle Animationen | |
Abstrakte Basisklasse für Gruppen von Animationen | |
Easing-Kurven zur Steuerung von Animationen | |
Parallele Gruppe von Animationen | |
Pause für QSequentialAnimationGroup | |
Animiert Qt-Eigenschaften | |
Sequentielle Gruppe von Animationen | |
Zeitleiste zur Steuerung von Animationen | |
Basisklasse für Animationen |
Animieren von Qt-Eigenschaften
Da die Klasse QPropertyAnimation auf Qt-Eigenschaften interpolieren kann, wird sie häufig verwendet. Ihre Superklasse -QVariantAnimation- stellt eine abstrakte Implementierung von updateCurrentValue() zur Verfügung, die keinen Wert ändert, es sei denn, Sie ändern ihn auf valueChanged signal.
Das Framework ermöglicht es Ihnen, die Qt-Eigenschaften der vorhandenen Klassen in Qt zu animieren. Die Klasse QWidget kann zum Beispiel in eine QGraphicsVieweingebettet werden und hat Eigenschaften für ihre Begrenzungen, Farben und so weiter. Das folgende Beispiel zeigt, wie Sie ein QPushButton Widget animieren können:
#include <QApplication> #include <QPushButton> #include <QPropertyAnimation> class MyButtonWidget : public QWidget { public: MyButtonWidget(QWidget *parent = nullptr); }; MyButtonWidget::MyButtonWidget(QWidget *parent) : QWidget(parent) { QPushButton *button = new QPushButton(tr("Animated Button"), this); QPropertyAnimation *anim = new QPropertyAnimation(button, "pos", this); anim->setDuration(10000); anim->setStartValue(QPoint(0, 0)); anim->setEndValue(QPoint(100, 250)); anim->start(); } int main(int argc, char *argv[]) { QApplication a(argc, argv); MyButtonWidget buttonAnimWidget; buttonAnimWidget.resize(QSize(800, 600)); buttonAnimWidget.show(); return a.exec(); }
Das Beispiel animiert die pos
Qt-Eigenschaft eines QPushButton, um es in 10 Sekunden (10000 Millisekunden) von der oberen linken Ecke des Bildschirms zur Endposition (250, 250) zu bewegen.
Es wird die Methode der linearen Interpolation verwendet, um die Geschwindigkeit der Animation zwischen dem Start- und dem Endwert zu steuern. Versuchen Sie, einen anderen Wert zwischen dem Start- und dem Endwert hinzuzufügen, um zu sehen, wie sie interpoliert werden. Verwenden Sie dieses Mal die Funktion QPropertyAnimation::setKeyValueAt, um diese Werte hinzuzufügen:
... anim->setDuration(10000); anim->setKeyValueAt(0, QPoint(0, 0)); anim->setKeyValueAt(0.8, QPoint(250, 250)); anim->setKeyValueAt(1, QPoint(0, 0)); ...
In diesem Beispiel bewegt die Animation die Schaltfläche in 8 Sekunden nach (250, 250) und in den verbleibenden 2 Sekunden zurück in ihre ursprüngliche Position. Die Bewegung der Schaltfläche wird zwischen diesen Punkten linear interpoliert.
Sie können auch einen Wert von QObject animieren, der nicht als Qt-Eigenschaft deklariert ist, wenn der Wert eine Setter-Methode hat. In solchen Fällen leiten Sie eine neue Klasse von der Klasse ab, die den Wert enthält, und fügen eine Qt-Eigenschaft für diesen Wert mit dem Setter hinzu.
Hinweis: Jede Qt-Eigenschaft erfordert auch einen Getter, so dass Sie einen Getter bereitstellen sollten, wenn dieser nicht definiert ist.
class MyGraphicsRectItem : public QObject, public QGraphicsRectItem { Q_OBJECT Q_PROPERTY(QPointF pos READ pos WRITE setPos) };
In diesem Beispiel leitet sich MyGraphicsRectItem
von QGraphicsRectItem und QObject ab und definiert die Eigenschaft pos
. Sie können das Element pos
animieren, auch wenn QGraphicsRectItem die Eigenschaft pos
nicht bereitstellt.
Eine allgemeine Einführung in das Eigenschaftssystem von Qt finden Sie unter Qt's Property System.
Animationen und das Graphics View Framework
QPropertyAnimation kann auch verwendet werden, um eine QGraphicsItem zu animieren, die nicht von QObject erbt. In solchen Fällen leiten Sie eine Klasse von dem Grafikelement ab, das Sie animieren möchten. Diese abgeleitete Klasse sollte auch von QObject erben, um die Verwendung von QPropertyAnimation auf QGraphicsItem zu ermöglichen. Das folgende Beispiel zeigt, wie dies geschieht:
class Pixmap : public QObject, public QGraphicsPixmapItem { Q_OBJECT Q_PROPERTY(QPointF pos READ pos WRITE setPos) ... }
Hinweis: Sie können auch von QGraphicsWidget ableiten, das bereits ein QObject ist.
Wie im vorigen Abschnitt beschrieben, müssen Sie die Eigenschaften definieren, die Sie animieren möchten. Die abgeleitete Klasse muss zunächst von QObject erben, da das Meta-Objektsystem dies erfordert.
Kurven glätten
Eine QPropertyAnimation führt eine lineare Interpolation zwischen den Werten der Start- und Endeigenschaften durch. Sie können der Animation nicht nur weitere Schlüsselwerte hinzufügen, sondern auch eine Entspannungskurve wählen, um die Geschwindigkeit der Interpolation zwischen 0 und 1 zu steuern, ohne den Pfad zu verändern.
MyButtonWidget::MyButtonWidget(QWidget *parent) : QWidget(parent) { QPushButton *button = new QPushButton(tr("Animated Button"), this); QPropertyAnimation *anim = new QPropertyAnimation(button, "pos", this); anim->setDuration(10000); anim->setStartValue(QPoint(0, 0)); anim->setEndValue(QPoint(100, 250)); anim->setEasingCurve(QEasingCurve::OutBounce); anim->start(); }
In diesem Beispiel folgt die Animation einer Kurve, die die button
wie einen Ball hüpfen lässt. QEasingCurve bietet eine große Sammlung von Kurven, die Sie aus der Aufzählung QEasingCurve::Type auswählen können. Wenn Sie eine andere Kurve verwenden möchten, die nicht verfügbar ist, implementieren Sie selbst eine und registrieren Sie sie bei QEasingCurve.
Gruppieren von Animationen
Eine Anwendung enthält oft mehr als eine Animation. Zum Beispiel möchte sie mehrere Grafikelemente gleichzeitig oder nacheinander bewegen.
Die Unterklassen von QAnimationGroup-QSequentialAnimationGroup und QParallelAnimationGroup- sind Container für andere Animationen, so dass diese Animationen entweder nacheinander oder parallel animiert werden können. QAnimationGroup animiert keine Eigenschaften, wird aber periodisch über Zeitänderungen informiert. Dadurch kann sie diese Zeitänderungen an die Animationsgruppen weiterleiten, die dann steuern, wann ihre Animationen abgespielt werden.
Die beiden folgenden Beispiele zeigen die Verwendung von QSequentialAnimationGroup und QParallelAnimationGroup:
MyButtonWidget::MyButtonWidget(QWidget *parent) : QWidget(parent) { QPushButton *bonnie = new QPushButton(tr("Bonnie"), this); QPushButton *clyde = new QPushButton(tr("Clyde"), this); QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "pos", this); anim1->setDuration(3000); anim1->setStartValue(QPoint(0, 0)); anim1->setEndValue(QPoint(100, 250)); QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "pos", this); anim2->setDuration(3000); anim2->setStartValue(QPoint(100, 250)); anim2->setEndValue(QPoint(500, 500)); QParallelAnimationGroup *parallelAnim = new QParallelAnimationGroup; parallelAnim->addAnimation(anim1); parallelAnim->addAnimation(anim2); parallelAnim->start(); }
Eine Parallelgruppe spielt mehr als eine Animation gleichzeitig ab. Ihre Funktion start() startet alle Animationen, die Teil der Gruppe sind.
MyButtonWidget::MyButtonWidget(QWidget *parent) : QWidget(parent) { QPushButton *bonnie = new QPushButton(tr("Bonnie"), this); QPushButton *clyde = new QPushButton(tr("Clyde"), this); QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "pos", this); anim1->setDuration(3000); anim1->setStartValue(QPoint(0, 0)); anim1->setEndValue(QPoint(100, 250)); QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "pos", this); anim2->setDuration(3000); anim2->setStartValue(QPoint(0, 0)); anim2->setEndValue(QPoint(200, 250)); QSequentialAnimationGroup *sequenceAnim = new QSequentialAnimationGroup; sequenceAnim->addAnimation(anim1); sequenceAnim->addAnimation(anim2); sequenceAnim->start(); }
Wie der Name schon sagt, spielt eine QSequentialAnimationGroup ihre Animationen nacheinander ab. Sie startet die nächste Animation in der Liste, nachdem die vorherige beendet ist.
Eine Gruppe ist selbst eine Animation, so dass Sie sie zu einer anderen Gruppe hinzufügen können. Auf diese Weise lässt sich ein Animationsbaum erstellen, der festlegt, wann die Animationen im Verhältnis zueinander abgespielt werden.
Objektbesitz
Ein QPropertyAnimation sollte immer einen Elternteil haben, der seine Lebensdauer kontrolliert. Eine typische Anwendung kann mehrere Animationen enthalten, die gruppiert sind, wobei die Animationsgruppe die Verantwortung für diese Animationen übernimmt. Einem unabhängigen QPropertyAnimation muss explizit ein Elternteil zugewiesen werden, um seine Lebensdauer zu kontrollieren. Im folgenden Beispiel sehen Sie, dass eine unabhängige QPropertyAnimation die Instanz QApplication als übergeordnetes Element hat:
#include <QApplication> #include <QPushButton> #include <QPropertyAnimation> class MyButtonWidget : public QWidget { public: MyButtonWidget(QWidget *parent = nullptr); }; MyButtonWidget::MyButtonWidget(QWidget *parent) : QWidget(parent) { QPushButton *button = new QPushButton(tr("Animated Button"), this); QPropertyAnimation *anim = new QPropertyAnimation(button, "pos", this); anim->setDuration(10000); anim->setStartValue(QPoint(0, 0)); anim->setEndValue(QPoint(100, 250)); anim->start(); } int main(int argc, char *argv[]) { QApplication a(argc, argv); MyButtonWidget buttonAnimWidget; buttonAnimWidget.resize(QSize(800, 600)); buttonAnimWidget.show(); return a.exec(); }
Hinweis: Sie können die Lebensdauer der Animation auch steuern, indem Sie beim Starten der Animation eine delete policy auswählen.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.