4.6がやってきた-Qt最新事情2010

第3回 Qt 4.6のアニメーションフレームワーク[後編]

この記事を読むのに必要な時間:およそ 7.5 分

グラフィックスビューのアイテムのアニメーション

グラフィックスビューのQGraphicsItemアイテムにアニメーションフレームワークを適用するには,QGraphicsItemアイテムのプロパティでアニメーションすることなります。しかし,ほとんどのQGraphicsItemアイテムはQObjectを継承してはいないので,そのようなアイテムでアニメーションするには,以下の2つの方法を用います。

  • 1.QGraphicsObjectをサブクラス化して,アイテムを作成する。
  • 2.QObjectとQGraphicsRectItemやQGraphicsPixmapItemを多重継承したアイテムを作成する。

QGraphicsSvgItem,QGraphicsTextItem,QGraphicsWidgetなどのようにQObjectを継承しているアイテムは,そのままでアニメーションを適用できます。

ここでは,2番目の方法でQGraphicsItemアイテムにアニメーションを適用してみましょう。

今回紹介するアニメーションプログラムのソースリストはこちらからダウンロードしてください。
examples.zip

リスト1 QGraphicsItemアイテムのアニメーション例(ボール移動アニメーション)

 1: #include <QApplication>
 2: #include <QGraphicsView>
 3: #include <QGraphicsScene>
 4: #include <QGraphicsPixmapItem>
 5: #include <QPropertyAnimation>
 6: #include <QLayout>
 7: #include <<QPushButton>
 8: 
 9: class MovableGraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
10: {
11:     Q_OBJECT
12:     Q_PROPERTY( QPointF pos READ pos WRITE setPos )
13: 
14: public:
15:     MovableGraphicsPixmapItem( const QPixmap& pixmap, QGraphicsItem* parent = 0 )
16:         : QObject(), QGraphicsPixmapItem( pixmap, parent ) {
17:     }
18: };
19: 

2番目の方法を用いた,QObjectとQGraphicsPixmapItemを多重継承したクラスです。posプロパティを既存のゲッターpos()とセッターsetPos()を用いて定義し,アイテムをプロパティを介して操作できるようすれば,アニメーションフレームワークが適用できるようになります。親のオブジェクトを指定せずに,QObjectを初期化することに注意します。

20: class HarnessPrivate
21: {
22: public:
23:     HarnessPrivate() 
24:         : movingAreaSize( QSize( 360, 120 ) ), horizontalOffset( 8 ) {
25:     }
26: 
27:     QSize movingAreaSize;
28:     int horizontalOffset;
29:     QPropertyAnimation* yellowBallAnimation;
30: };
31: 
32: class Harness : public QWidget
33: {
34:     Q_OBJECT
35:     Q_DECLARE_PRIVATE( Harness )
36: 
37: public:
38:     Harness();
39:     ~Harness();
40: 
41: private slots:
42:     void startAnimation();
43: 
44: private:
45:     MovableGraphicsPixmapItem* createBallItem( const QString& pixmapFileName );
46:     HarnessPrivate* d_ptr;
47: };
48: 

動くアイテムがあるグラフィックスビューを置くためのクラスです。今迄のサンプルプログラムと同じように,Animate ボタンがクリックされたならば,startAnimation() スロットを呼出して,アニメーションを開始するようにします。

49: Harness::Harness()
50:     : QWidget( 0 ), d_ptr( new HarnessPrivate )
51: {
52:     Q_D( Harness );
53: 
54:     QGraphicsScene* graphicsScene = new QGraphicsScene( 0, 0, d->>movingAreaSize.width(), d->movingAreaSize.height() );
55:     MovableGraphicsPixmapItem* yellowBallItem = createBallItem( ":/images/YellowGlassBall.png" );
56:     QSize ballSize = yellowBallItem->pixmap().size();
57:     int ballSpacingY = ( d->movingAreaSize.height() - ballSize.height())  / 2;
58:     int yellowBallY = ballSpacingY;
59:     yellowBallItem->setPos( d->horizontalOffset, yellowBallY );
60:     graphicsScene->addItem( yellowBallItem );
61: 

グラフィックスシーンの左端に,アニメーションが可能なようにしたアイテムを配置しています。

62:     QGraphicsView* graphicsView = new QGraphicsView();
63:     graphicsView->setScene( graphicsScene );
64: 
65:     QPushButton* animateButton = new QPushButton( "Animate" );
66: 
67:     QHBoxLayout* buttonLayout = new QHBoxLayout;
68:     buttonLayout->addStretch();
69:     buttonLayout->addWidget( animateButton );
70: 
71:     QVBoxLayout* topLayout = new QVBoxLayout;
72:     topLayout->addWidget( graphicsView );
73:     topLayout->addLayout( buttonLayout );
74: 
75:     setLayout( topLayout );
76:     setFixedSize( sizeHint() );
77: 
78:     d->yellowBallAnimation = new QPropertyAnimation( yellowBallItem, "pos", this );
79:     d->yellowBallAnimation->setDuration( 5 * 1000 );
80:     int movableBallStartX = d->horizontalOffset;
81:     int movableBallEndX = d->movingAreaSize.width() - ballSize.width() - d->horizontalOffset;
82:     d->yellowBallAnimation->setStartValue( QPoint( movableBallStartX, yellowBallY ) );
83:     d->yellowBallAnimation->setEndValue( QPoint( movableBallEndX, yellowBallY ) );
84:     d->yellowBallAnimation->setEasingCurve( QEasingCurve::OutBounce );
85: 

posプロパティを使ってアニメーションするのは,今までのサンプルプログラムとまったく同じようになります。つまり,QObjectを継承するQtのオブジェクトは,グラフィカルなものも非グラフィカルなものも,アニメーションフレームワークを用いてアニメーションできるのです。

 86:     connect( animateButton, SIGNAL( clicked() ), SLOT( startAnimation() ) );
 87: }
 88: 
 89: Harness::~Harness()
 90: {
 91:     delete d_ptr;
 92: }
 93: 
 94: void Harness::startAnimation()
 95: {
 96:     Q_D( Harness );
 97:     
 98:     d->yellowBallAnimation->start();
 99: }
100: 
101: MovableGraphicsPixmapItem* Harness::createBallItem( const QString& pixmapFileName )
102: {
103:     MovableGraphicsPixmapItem* item = new MovableGraphicsPixmapItem( QPixmap( pixmapFileName ) );
104: 
105:     return item;
106: }
107: 
108: int main( int argc, char** argv )
109: {
110:     QApplication app( argc, argv );
111: 
112:     Harness harness;
113:     harness.show();
114: 
115:     return app.exec();
116: }
117: 
118: #include "movablegraphicsitem.moc"

リスト1のサンプルプログラムを実行すると,以下の動画のように黄色いボールが左から右に移動します。

ボール移動アニメーション

著者プロフィール

杉田研治(すぎたけんじ)

1955年生まれ。東京都出身。株式会社SRAに勤務。プログラマ。

仕事のほとんどをMac OS XとKubuntu KDE 4でQtと供に過ごす。

コメント

コメントの記入