En esta página

Estructura de animación

El marco de animación proporciona una forma sencilla de animar los elementos de la interfaz gráfica de usuario. Te permite animar el valor de una propiedad Qt de un widget o QObject. La mayoría de las características que ofrece el framework también están disponibles en Qt Quickdonde es posible definir animaciones de forma declarativa.

Esta visión general explica la arquitectura del framework, con ejemplos que demuestran las técnicas comunes utilizadas para animar QObject y elementos GUI.

La arquitectura de animación

El siguiente diagrama muestra las clases más importantes proporcionadas por el framework:

La jerarquía de clases de Animation Framework.

Incluye la clase QAbstractAnimation, que proporciona la base necesaria para las animaciones. Esta clase define las propiedades genéricas para todas las animaciones soportadas por el framework. Por ejemplo, la capacidad de iniciar, detener y pausar una animación. La clase también recibe las notificaciones de cambio de tiempo.

El marco proporciona además las clases QVariantAnimation y QAnimationGroup, que se basan en su caso base, QAbstractAnimation. La siguiente en la jerarquía es QPropertyAnimation, que deriva de QVariantAnimation, y te permite animar una propiedad Qt de un widget o QObject. La clase realiza una interpolación en el valor de la propiedad utilizando una curva de relajación. Con esto en su lugar, sólo necesitas una clase QObject con un valor de propiedad Qt que puedas animar.

Nota: Es necesario que el objeto de destino que está animando sea un QObject o su subclase. Esto es necesario ya que el framework de animación depende del sistema de meta-objetos para toda la información sobre el objeto que está animando.

Se pueden construir animaciones complejas construyendo una estructura de árbol de QAbstractAnimations, donde el árbol es un QAnimationGroup que contiene otras animaciones. Estos grupos de animación también pueden contener subgrupos que representan diferentes grupos o animaciones, como QParallelAnimationGroup y QSequentialAnimationGroup.

Entre bastidores, todas las animaciones están controladas por un temporizador global, que envía updates sobre todas las animaciones que se están ejecutando.

Para obtener información detallada sobre cada una de estas clases y su función en el framework, consulta su documentación.

Clases que ofrece el framework

Estas clases proporcionan la infraestructura necesaria para crear animaciones simples y complejas.

QAbstractAnimation

La base de todas las animaciones

QAnimationGroup

Clase base abstracta para grupos de animaciones

QEasingCurve

Curvas de animación para controlar la animación

QParallelAnimationGroup

Grupo paralelo de animaciones

QPauseAnimation

Pausa para QSequentialAnimationGroup

QPropertyAnimation

Anima propiedades Qt

QSequentialAnimationGroup

Grupo secuencial de animaciones

QTimeLine

Línea de tiempo para controlar animaciones

QVariantAnimation

Clase base para animaciones

Animación de propiedades Qt

Dado que la clase QPropertyAnimation puede interpolar propiedades Qt, se utiliza a menudo. De hecho, su superclase -QVariantAnimation- proporciona una implementación abstracta de updateCurrentValue(), que no cambia ningún valor a menos que lo cambies en valueChanged signal.

El framework te permite animar las propiedades Qt de las clases existentes en Qt. Por ejemplo, la clase QWidget -que puede incrustarse en un QGraphicsView- tiene propiedades para sus límites, colores, etc. El siguiente ejemplo demuestra cómo se puede animar un widget QPushButton:

#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();
}

El ejemplo anima la propiedad Qt pos de un QPushButton, para moverlo desde la esquina superior izquierda de la pantalla hasta la posición final (250, 250), en 10 segundos (10000 milisegundos).

Utiliza el método de interpolación lineal para controlar la velocidad de la animación entre los valores inicial y final. Intenta añadir otro valor entre el valor inicial y el final para ver cómo se interpolan. Esta vez utiliza la función QPropertyAnimation::setKeyValueAt() para añadir estos valores:

...
anim->setDuration(10000);
anim->setKeyValueAt(0, QPoint(0, 0));
anim->setKeyValueAt(0.8, QPoint(250, 250));
anim->setKeyValueAt(1, QPoint(0, 0));
...

En este ejemplo, la animación mueve el botón a (250, 250) en 8 segundos, y lo devuelve a su posición original en los 2 segundos restantes. El movimiento del botón se interpola linealmente entre estos puntos.

También puede animar un valor de QObject que no esté declarado como propiedad Qt, si el valor tiene un método setter. En tales casos, derive una nueva clase de la clase que contiene el valor, y añada una propiedad Qt para ese valor con el setter.

Nota: Cada propiedad Qt requiere también un getter, por lo que debes proporcionar un getter si no está definido.

class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
{
    Q_OBJECT
    Q_PROPERTY(QPointF pos READ pos WRITE setPos)
};

En este ejemplo, MyGraphicsRectItem deriva de QGraphicsRectItem y QObject, y define la propiedad pos. Puede animar el elemento pos incluso si QGraphicsRectItem no proporciona la propiedad pos.

Para una introducción general al sistema de propiedades de Qt, consulte Sistema de propiedades de Qt.

Animaciones y Graphics View Framework

QPropertyAnimation también se puede utilizar para animar un QGraphicsItem, que no hereda QObject. En tales casos, se deriva una clase del elemento gráfico que se desea animar. Esta clase derivada también debe heredar de QObject para poder utilizar QPropertyAnimation en QGraphicsItem. El siguiente ejemplo muestra cómo hacerlo:

class Pixmap : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT
    Q_PROPERTY(QPointF pos READ pos WRITE setPos)
    ...
}

Nota: También puede derivar de QGraphicsWidget, que ya es un QObject.

Como se ha descrito en la sección anterior, debe definir las propiedades que desea animar. La clase derivada debe heredar primero de QObject, ya que el sistema de metaobjetos así lo requiere.

Animación de curvas

Un QPropertyAnimation realiza una interpolación lineal entre los valores iniciales y finales de la propiedad. Además de añadir más valores clave a la animación, también puedes elegir una curva de flexibilización para controlar la velocidad de interpolación entre 0 y 1, sin cambiar la trayectoria.

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();
}

En este ejemplo, la animación sigue una curva que hace que button rebote como una pelota. QEasingCurve ofrece una amplia colección de curvas para elegir en el enum QEasingCurve::Type. Si quieres utilizar otra curva que no esté disponible, implementa una tú mismo y regístrala en QEasingCurve.

Agrupar animaciones

Una aplicación contiene a menudo más de una animación. Por ejemplo, quiere mover más de un elemento gráfico simultáneamente o moverlos en secuencia uno tras otro.

Las subclases de QAnimationGroup-QSequentialAnimationGroup y QParallelAnimationGroup- son contenedores de otras animaciones para que éstas puedan animarse en secuencia o en paralelo. QAnimationGroup no anima propiedades, pero recibe notificaciones periódicas de los cambios de hora. Esto le permite reenviar esos cambios de tiempo a los grupos de animación, que controlan cuándo se reproducen sus animaciones.

Los dos ejemplos siguientes muestran el uso de QSequentialAnimationGroup y 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();
}

Un grupo paralelo reproduce más de una animación al mismo tiempo. Su función start() inicia todas las animaciones que forman parte del grupo.

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();
}

Como su nombre indica, un QSequentialAnimationGroup reproduce sus animaciones en secuencia. Comienza la siguiente animación de la lista después de que termine la anterior.

Un grupo es una animación en sí misma, por lo que puedes añadirla a otro grupo. De esta forma, se construye un árbol de animación, que define cuándo se reproducen las animaciones en relación unas con otras.

Propiedad del objeto

Un QPropertyAnimation siempre debe tener un padre que controle su tiempo de vida. Una aplicación típica puede incluir varias animaciones que están agrupadas, donde el grupo de animación toma la propiedad de esas animaciones. A un QPropertyAnimation independiente se le debe asignar explícitamente un padre que controle su tiempo de vida. En el siguiente ejemplo, puede ver que un QPropertyAnimation independiente tiene la instancia QApplication como padre:

#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();
}

Nota: También puedes controlar el tiempo de vida de la animación eligiendo un delete policy al iniciarla.

© 2026 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.