ボタンやスライダーがウィンドウの端から動いて現れるようにするような効果を簡潔に実装できます。
アニメーションフレームワークの関連クラス
図1は、アニメーションフレームワークに用意されているクラスの概要です。
QPropertyAnimationクラスは、Qtのプロパティを動的に変更して、アニメーションをできるようにします。複数のアニメーションをつなぎ合わせたり、並列に動作させるには、QSequentialAnimationGroupとQParallelAnimationGroupを使います。これらの3つのクラスがアニメーションでよく使われ、QPauseAnimationがQSequentialAnimationGroup内のアニメーション間に一時停止時間を入れるために使われます。
今回紹介するアニメーションプログラムのソースリストはこちらからダウンロードしてください。
examples.zip
ウィジェットのアニメーション
次の動画のように、ラベルを左から右に移動させるプログラムについて説明します。このプログラムでは、図2のように一定の速度でラベルを移動させています。
動くラベルを置くためのクラスです。Animate ボタンがクリックされたならば、startAnimation()スロットを呼出して、アニメーションを開始するようにします。
動かすラベルはレイアウト機能を使って並べずに、直に位置と大きさを指定することに注意しましょう。
動かさないボタンは、レイアウト機能を使ってきれいに並べます。ラベルが動く領域を確保するために、addSpacing()で高さが固定された空白領域が取られるように調整し、ウィンドウサイズ変更時の処理を省いているので、ウィンドウサイズを固定しています。
QPropertyAnimationのインスタンス生成で、第一引数にアニメーション対象のオブジェクトを指定し、第二引数にアニメーションで変化させるプロパティ名を指定します。QWidgetクラスでは、posプロパティが以下のように定義されています。
QPropertyAnimation によって、posプロパティが変更される際には、アニメーション処理の内部では、Qtのメタオブジェクトシステムの機能を用いて、文字列 "pos"からmove()メソッドが求められて呼出され、ウィジェットの位置が変更されます。
setDuration()でアニメーションの動作時間を5秒に設定し、setStartValue()とsetEndValue()でアニメーションの開始値と終了値を設定しています。
Animateボタンをクリックすると、このstartAnimation()スロットが呼び出され、labelAnimationのstart()を呼んでアニメーションを開始し、ラベルを左から右へ移動させます。このように開始値と終了値のみを設定した場合には、これらの2値を線形補間して移動が行われます。
アニメーション可能なプロパティ
先の例では、ラベルのposプロパティを変更して、その位置を動かしました。アニメーションの時間とその開始値と終了値を指定しただけで、自動的に滑らかに動くように位置が変更されました。開始値は、QVariantAnimationクラスのstartValueプロパティで、終了値はendValueプロパティ。共に型はQVariantです。つまり、QVariant型の2つの値間を補間して、アニメーションが行われていることになります。
QVariantには、QStringやQPixmapなども格納できますが、このような型のプロパティには、自明な補間方法がないので、プロパティのアニメーションの対象ではありません。アニメーション可能なプロパティの型は、表1のようになっています。
表1 アニメーション対応のプロパティ一覧
メタタイプ | 実際の型 |
QMetaType::Int | int |
QMetaType::Double | double |
QMetaType::Float | float |
QMetaType::QLine | QLine |
QMetaType::QLineF | QLineF |
QMetaType::QPoint | QPoint |
QMetaType::QSize | QSize |
QMetaType::QSizeF | QSizeF |
QMetaType::QRect | QRect |
QMetaType::QRectF | QRectF |
したがってQWidgetでは、表1に挙げた型を持つプロパティ、たとえばpos(QPoint)、geometry(QRect)、windowOpacity(double)などのプロパティがアニメーションの対象になります。最初のサンプルプログラムでは、posプロパティを変更してラベルを横方向に移動しているので、xプロパティをアニメーションしても同様な効果が得られます。
キーバリューによるアニメーション速度の変更
一定の速度でラベルを移動させるのではなく、キーバリュー指定によって、アニメーションの速度を変更してみましょう。リスト1の68~73行目を次のように変更します。
setStartValue()とsetEndValue()の代わりにsetKeyValueAt()を用いて、第一引数で時間経過の割合を0.0から1.0の間の値で指定し、第二引数で対応する経過値を指定します。この場合には図3に示すように、アニメーション時間が5秒で、0.5の割合の時間経過での経過値を9割の位置にしているので、アニメーションの開始から 2.5秒経過した時刻で、9割の移動が行われるようになります。
この修正をしたサンプルプログラムを動作させると、次のようなアニメーションになります。
イージングによるアニメーション速度の変更
イージングとは、ボールが跳ねたりする動きのように、加速度を考慮したアニメーションをを実現する方法です。イージングによって、加速、減速、加減速、跳ねるなどのアニメーション効果を得られます。この場合は、リスト1の68行目~を次のように変更します。
最初のサンプルプログラム(リスト1)に74 行目の行を追加すると、横向きの移動ですが、次の動画のように、跳ねるようなアニメーション効果が得られます。
イージングを使うには、setEasingCurve() で、イージングカーブをアニメーションに指定します。ここで指定している QEasingCurve::OutBounce は、アニメーション動作が終了する前(Out)に、跳ねる(Bounce)ように位置が変わります。
Qtでは、Robert PennerのイージングカーブをQEasingCurveで実装しています。イージングは、表2の4つの加速/減速方法と10種類の補間曲線を組み合わせて、40種類あります。
表2 イージングの種類
加速と減速方法 |
In | 加速 |
Out | 減速 |
InOut | 加速後に減速 |
OutIn | 減速後に加速 |
補間曲線 |
Sine | 正弦曲線に沿う |
Quad | 2 次曲線に沿う |
Cubic | 3 次曲線に沿う |
Quart | 4 次曲線に沿う |
Quint | 5 次曲線に沿う |
Expo | 指数曲線に沿う |
Circ | 円弧に沿う |
Elastic | 弾む動き |
Back | 行き過ぎて戻る動き |
Bounce | 跳ねる動き |
Qtで用意されているイージングには、これらに加えLinear(加減速のない線形補間)や、ユーザ定義のCustomがあります。Qtのパッケージ中のexamples/animation/easingディレクトリにあるEasing Curves Exampleで、イージングカーブが適用されたアニメーションの動作を確かめられます。