このページでは

アニメーションフレームワーク

アニメーションフレームワークは、GUI要素にアニメーションを適用するための簡単な方法を提供します。これにより、ウィジェットやQObject のQtプロパティ値にアニメーションを適用できます。このフレームワークが提供する機能のほとんどは、 Qt Quickでも利用可能であり、そこでは宣言的な方法でアニメーションを定義することができます。

この概要では、フレームワークのアーキテクチャについて説明するとともに、QObject や GUI 要素にアニメーションを適用するために一般的に使用される手法を示す例を紹介します。

アニメーションのアーキテクチャ

次の図は、このフレームワークが提供する最も重要なクラスを示しています:

アニメーション・フレームワークのクラス階層。

これには、アニメーションに必要な基盤を提供するQAbstractAnimation クラスが含まれます。このクラスは、フレームワークがサポートするすべてのアニメーションに共通するプロパティを定義しています。例えば、アニメーションの開始、停止、一時停止などの機能です。また、このクラスは時間の変更通知を受け取ります。

さらに、このフレームワークは、基底クラスであるQAbstractAnimation を基に構築されたQVariantAnimation クラスとQAnimationGroup クラスを提供します。階層の次には、QVariantAnimation から派生したQPropertyAnimation があり、これによりウィジェットのQtプロパティやQObject をアニメーション化できます。このクラスは、イージングカーブを使用してプロパティ値の補間を行います。 これらを用意すれば、アニメーション化可能なQtプロパティ値を持つQObject クラスさえあれば十分です。

注: アニメーションの対象となるオブジェクトは、QObject またはそのサブクラスである必要があります 。これは、アニメーションフレームワークが、アニメーションの対象となるオブジェクトに関するすべての情報をメタオブジェクトシステムに依存しているためです。

複雑なアニメーションは、QAbstractAnimationのツリー構造を構築することで作成できます。このツリーは、他のアニメーションを含むQAnimationGroup です。これらのアニメーショングループには、QParallelAnimationGroup やQSequentialAnimationGroup など、さまざまなグループやアニメーションを表すサブグループを含めることもできます。

内部的には、すべてのアニメーションはグローバルタイマーによって制御されており、このタイマーは実行中のすべてのアニメーションに関する情報を `updates ` に送信します。

これらの個々のクラスおよびフレームワーク内での役割に関する詳細については、各クラスのドキュメントを参照してください。

フレームワークが提供するクラス

これらのクラスは、単純なアニメーションから複雑なアニメーションまでを作成するために必要なインフラストラクチャを提供します。

QAbstractAnimation

すべてのアニメーションの基盤

QAnimationGroup

アニメーションのグループのための抽象基底クラス

QEasingCurve

アニメーションを制御するためのイージングカーブ

QParallelAnimationGroup

並列アニメーショングループ

QPauseAnimation

QSequentialAnimationGroup の一時停止

QPropertyAnimation

Qtプロパティをアニメーション化する

QSequentialAnimationGroup

アニメーションのシーケンシャルグループ

QTimeLine

アニメーション制御用のタイムライン

QVariantAnimation

アニメーションの基底クラス

Qtプロパティのアニメーション化

QPropertyAnimation クラスはQtプロパティに対して補間処理を行うことができるため、頻繁に使用されます。実際、そのスーパークラスであるQVariantAnimationは、updateCurrentValue()の抽象実装を提供しており、valueChanged signal 上で変更を加えない限り、値は一切変更されません。

このフレームワークを使用すると、Qtに存在するクラスのQtプロパティをアニメーション化できます。たとえば、QWidget クラスは(QGraphicsViewに埋め込むことができますが)、境界や色などのプロパティを持っています。次の例は、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();
}

この例では、QPushButton のpos というQtプロパティをアニメーション化し、画面の左上隅から終点(250, 250)まで、10秒(10000ミリ秒)かけて移動させます。

ここでは、開始値と終了値間のアニメーション速度を制御するために、線形補間法を使用しています。開始値と終了値の間に別の値を追加して、それらがどのように補間されるかを確認してみてください。今回は、QPropertyAnimation::setKeyValueAt() 関数を使用してこれらの値を追加します:

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

この例では、アニメーションによってボタンが8秒かけて(250, 250)まで移動し、残りの2秒で元の位置に戻ります。ボタンの移動は、これらの点間で線形補間されます。

また、その値にセッターメソッドがあれば、Qtプロパティとして宣言されていないQObject の値をアニメーション化することも可能です。そのような場合は、その値を含むクラスを基底クラスとして新しいクラスを派生させ、セッター付きのQtプロパティをその値に対して追加してください。

注:各Qt プロパティにはゲッターも必要となるため、ゲッターが定義されていない場合は、ゲッターも提供する必要があります。

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

この例では、MyGraphicsRectItem はQGraphicsRectItem およびQObject を継承し、pos プロパティを定義しています。QGraphicsRectItem がpos プロパティを提供していない場合でも、この項目のpos をアニメーション化することができます。

Qtのプロパティシステムに関する一般的な概要については、「Qtのプロパティシステム」を参照してください。

アニメーションとグラフィックスビューフレームワーク

QPropertyAnimation は、QObject を継承していないQGraphicsItem をアニメーション化するためにも使用できます。そのような場合、アニメーション化したいグラフィックスアイテムからクラスを派生させます。この派生クラスは、QGraphicsItem に対してQPropertyAnimation を使用できるようにするため、QObject も継承する必要があります。以下の例は、その方法を示しています:

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

注: すでにQObject であるQGraphicsWidget から派生させることも可能です 。

前のセクションで説明したように、アニメーション化したいプロパティを定義する必要があります。メタオブジェクトシステムではこれが必須であるため、派生クラスはまずQObject を継承する必要があります。

イージングカーブ

QPropertyAnimation は、プロパティの開始値と終了値の間で線形補間を行います。アニメーションにキーフレームを追加するだけでなく、イージングカーブを選択することで、経路を変更することなく、0から1までの補間の速度を制御することもできます。

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

この例では、アニメーションはbutton をボールのように跳ねさせる曲線に従っています。QEasingCurve では、QEasingCurve::Type 列挙型から選択できる豊富な曲線が用意されています。利用可能な曲線以外のものを使用したい場合は、独自に実装し、QEasingCurve で登録してください。

アニメーションのグループ化

アプリケーションには、多くの場合、複数のアニメーションが含まれています。たとえば、複数のグラフィックアイテムを同時に移動させたり、順番に連続して移動させたりする場合があります。

QAnimationGroupのサブクラスであるQSequentialAnimationGroup とQParallelAnimationGroupは、他のアニメーションを格納するコンテナであり、これらのアニメーションを順次または並行して再生できるようにします。QAnimationGroup はプロパティをアニメーション化することはありませんが、定期的に時間の変更通知を受け取ります。これにより、 はそれらの時間の変更をアニメーショングループに転送することができ、アニメーショングループはアニメーションの再生タイミングを制御します。

以下の 2 つの例は、QSequentialAnimationGroup と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();
}

並列グループは、複数のアニメーションを同時に再生します。その `start()` 関数は、グループに属するすべてのアニメーションを開始します。

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

その名前が示す通り、QSequentialAnimationGroup はアニメーションを順番に再生します。前のアニメーションが終了すると、リスト内の次のアニメーションを開始します。

グループはそれ自体がアニメーションであるため、別のグループに追加することができます。これにより、アニメーションツリーを構築し、アニメーション同士の再生順序を定義することができます。

オブジェクトの所有権

QPropertyAnimation には、そのライフサイクルを制御する親が常に存在する必要があります。一般的なアプリケーションでは、グループ化された複数のアニメーションが含まれており、その場合、アニメーショングループがそれらのアニメーションの所有権を持ちます。独立したQPropertyAnimation には、そのライフサイクルを制御するために親を明示的に割り当てる必要があります。次の例では、独立したQPropertyAnimation がQApplication インスタンスを親として持っていることがわかります:

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

注: アニメーションを開始する際に「delete policy 」を選択することで、アニメーションの存続期間を制御することもできます。

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