Qt 4.6を試す:Qtアニメーションとステートマシン

画像

先日、いわゆる「技術プレビュー」Qt 4.6がリリースされました。これにより、このすばらしいフレームワークのリリース4.6に含まれる新機能を試すことができます。 イノベーションはリストしません-それらはこのトピックで十分にカバーされましたが、それらのうちの2つ、State MachineとQt Animation Framevorkについて詳しく説明します。



それで彼らは何が好きですか?



ステートマシンは、有限のステートマシンにすぎません。状態と状態間の遷移が事前に定義された有限数のオブジェクトです。

Qt 4.6では、このように実装されます。必要な状態の数を作成し、各状態について、この状態で各オブジェクトが持つプロパティを示し、状態間の遷移を設定し、開始点を指定して、実行するマシンを起動します。



しかし、最初に、Qt 4.6自体が必要です。 Linuxのソースからビルドする方法を説明します(すべてのディストリビューションに適用可能)。 MinGWを事前にインストールしておけば、Windowsでのビルドはそれほど変わりません。 おそらく、MSVSを使用してビルドできますが、私は自分で試したことはありません。



Qt 4.6ビルド



リポジトリからインストールされた現在のバージョンに「悪影響」を与えずにQt 4.6をビルドする方法について説明します。 おそらく私の方法は最適ではありませんが、少なくとも動作します:)

すぐに警告します:ビルドするには、〜3 GBのディスク容量が必要で、インストールにはさらに〜900 MBが必要です(アセンブリの残りはすべて削除できます)。 デバッグ情報が含まれているため(これはリリースではないため)、ライブラリだけでなく、例、ドキュメントなども含まれているため、非常に時間がかかります。

開始するには、 ここ(tar.gz)またはここ(zip)からソースコードダウンロードします。 展開し、ソースディレクトリに移動し、構成を実行します

  $ ./configure --prefix = / opt / Qt4.6 


同様の接頭辞を指定することにより、1つの石で2羽の鳥を殺します。1)既にインストールされているバージョンには影響しません。 2)その後、「手首のフリック」ですべてを削除できます。

構成プロセス中に、彼らはライセンスについて質問します。「about」(GPLおよびLGPLを含むオープンソースバージョン)に答え、それに同意し(「yes」など)、数分待ちます。 終了後、構成のプレフィックスを再度お知らせします。

さて、最後に、アセンブリ! 打ち上げ
  $ make 


そして、私たちは待っています。 待っています。 私たちは待っています...

アセンブリの進行中、お茶やコーヒーを作るだけでなく、部屋で掃除をすることもできます。私のクアッドコアでは、4スレッドでのアセンブリに40分かかりました。 スレッドの数(プロセッサコアの数による)は、「-j」オプションを使用して指定できます。

  $ make -j 4 


アセンブリが完了したら、次を使用してインストールします
  $ sudo make install 


一般的な場合、このようなインストールは非常に望ましくありませんが、この特定のケースでは、それを購入する余裕があります。 目的のプレフィックスを示すことで自身を保護し、これによるシステムの調和は特に影響を受けません。



カスタマイズ



次に、システムにインストールされているバージョンではなく、新しいバージョンを使用できるようにする必要があります。 これに必要なのは、正しいqmakeを使用することです。彼は必要なインクルードとライブラリを選択し、それらを使用してMakefileを生成します。

ここには3つの異なるオプションがあります。

  1. 毎回フルパスでqmakeを呼び出します。
      $ /opt/Qt4.6/bin/qmake 


  2. 端末セッションの間、qmakeのパスを設定します。
      $ export PATH = / opt / Qt4.6 / bin:$ PATH 


  3. 上記の行を〜/ .bashrcに記述すると、このqmakeが常に使用されます


私は2番目のオプションを使用します-実験ではこれで十分です。



お試しください



すべてが正しく行われたことを確認するには、小さなプログラムをコンパイルします。

  $ mkdir qt_anim
 $ cd qt_anim
 $(vim | emacs | nano | kate | gedit | juffed | ...)anim.cpp 


anim.cpp:

Copy Source | Copy HTML<br/><br/> #include < QApplication ><br/> #include < QWidget ><br/> <br/> int main( int argc, char * argv []) {<br/> QApplication app(argc, argv );<br/> QWidget w;<br/> w.resize( 200 , 100 );<br/> w.show();<br/> return app.exec();<br/>}<br/> <br/>





  $ qmake -project
 $ qmake
 $ make
 $ ldd qt_anim |  grep Qt 




その後、頼りにしているライブラリが使用されていることを報告する必要があります。 そうでない場合は、正しいqmakeバージョンを使用していることを確認してください。

  qmake 


バージョンが同じでない場合は、PATHの設定と間違えていないことを確認してください。



さあ始めましょう!



最初に、State Machineが何であり、それが何で食べられるかを理解しましょう。 タスクを設定します:隅に小さな画像が表示されるウィンドウを作成します。ウィンドウをクリックすると、ウィンドウが移動してサイズが大きくなります。



anim.cpp:

Copy Source | Copy HTML<br/> #include < QApplication ><br/> #include "AnimWidget.h" <br/> <br/> int main( int argc, char * argv []) {<br/> QApplication app(argc, argv );<br/> AnimWidget w;<br/> w.resize( 300 , 300 );<br/> w.show();<br/> return app.exec();<br/>}<br/> <br/> <br/>







AnimWidget.h:

Copy Source | Copy HTML<br/> #ifndef __ANIM_WIDGET_H__<br/> #define __ANIM_WIDGET_H__<br/> <br/> #include < QLabel ><br/> #include < QStateMachine ><br/> #include < QWidget ><br/> <br/> class AnimWidget : public QWidget {<br/>Q_OBJECT<br/> public :<br/> AnimWidget ();<br/> <br/>signals:<br/> /* signal for triggering state machine changes */ <br/> void clicked();<br/> <br/> protected :<br/> /* here we will be catching clicks */ <br/> virtual void mouseReleaseEvent(QMouseEvent*);<br/> <br/> private :<br/> QStateMachine machine_;<br/> QLabel * photo_;<br/>};<br/> <br/> #endif // __ANIM_WIDGET_H__ <br/> <br/>







AnimWidget.cpp:

Copy Source | Copy HTML<br/> #include "AnimWidget.h" <br/> <br/> #include < QState ><br/> #include < QVariant ><br/> <br/>AnimWidget::AnimWidget() {<br/> photo_ = new QLabel ( "" , this );<br/> photo_->setGeometry( 0 , 0 , 40 , 40 );<br/> photo_->setScaledContents( true );<br/> photo_->setPixmap(QPixmap( "ottawa.png" ));<br/> <br/> /* creating 2 states */ <br/> QState * st1 = new QState ();<br/> QState * st2 = new QState ();<br/> <br/> /* defining photo's properties for each of them */ <br/> st1->assignProperty(photo_, "geometry" , QRect( 0 , 0 , 40 , 40 ));<br/> st2->assignProperty(photo_, "geometry" , QRect( 50 , 50 , 200 , 200 ));<br/> <br/> /* define transitions between states by clicking on main window*/ <br/> st1->addTransition( this , SIGNAL(clicked()), st2);<br/> st2->addTransition( this , SIGNAL(clicked()), st1);<br/> <br/> /* adding states to state machine */ <br/> machine_.addState(st1);<br/> machine_.addState(st2);<br/> machine_.setInitialState(st1);<br/> <br/> /* starting machine */ <br/> machine_.start();<br/>}<br/> <br/> void AnimWidget::mouseReleaseEvent(QMouseEvent*) {<br/> emit clicked();<br/>}<br/> <br/>







行に

  st1-> assignProperty(photo_、 "geometry"、QRect(0、0、40、40));
 st2-> assignProperty(photo_、 "geometry"、QRect(50、50、200、200)); 


いずれかの状態に固有のオブジェクトのプロパティが設定されます。 標準のQtベースのクラスには特定のプロパティセットが含まれており、独自のクラスのプロパティを設定するには、Q_PROPERTYを使用します( ドキュメントを参照)。





  st1-> addTransition(this、SIGNAL(clicked())、st2);
 st2-> addTransition(this、SIGNAL(clicked()))、st1); 


状態間の遷移とこれらの遷移の条件を決定します。 この場合、遷移条件は、メインウィンドウによってスローされるclicked()シグナルになります。

状態間の遷移は無条件にすることができます-オブジェクトと信号は示されませんが、最終状態は単純に示されます( ドキュメントを参照)。



また、「ottawa.png」の代わりに別の画像を指定して、ソースの横に置くことを忘れないでください(または、以下のリンクからソースをダウンロードしてください)。



収集するもの:

  $ qmake -project
 $ qmake
 $ make
 $ ./qt_anim 




クリック-ジャンプ!

しかし、すぐにジャンプします。 はい、マシンの状態間の遷移は即座に発生します-しかし、これは私たちが望むものではありませんか? 状態間の遷移にアニメーションを追加しましょう。 これを行うには、「machine_.start();」行の前に次のコードを追加します。

Copy Source | Copy HTML<br/>...<br/> /* adding animation */ <br/> QPropertyAnimation * an1 = new QPropertyAnimation (photo_, "geometry" );<br/>machine_.addDefaultAnimation(an1);<br/>...<br/> <br/>





追加することを忘れないでください
  #include <QPropertyAnimation> 
ファイルの先頭まで。



ここでは、原則として、すべてが明確です。photo_オブジェクトのジオメトリ属性を変更するアニメーションを作成し、アニメーションを車に追加します。



組み立て、立ち上げ...



はるかに良いですね 写真はジャンプしませんが、サイズが変化して新しい場所にスムーズに移動します。



さまざまなアニメーションパラメータを変更できます。特に、継続時間と「加速曲線」を設定できます。 画像の動きを速くしてから、遅くすることができます。 ゆっくり開始してから加速することも可能です。 または、ゆっくり開始し、加速し、その後徐々に減速するようにすることもできます。 可能なオプションは数十あります( ドキュメントを参照)。 私は、速度が3倍に変化する「加速-ブレーキ」オプションを選択しました。 アニメーションを作成した後、次の行を追加します。

Copy Source | Copy HTML<br/>...<br/> /* customizing the animation */ <br/>an1->setEasingCurve(QEasingCurve::InOutCubic);<br/>an1->setDuration( 700 );<br/>... <br/>







まあ、今では一定の速度で退屈な動きの代わりに、写真はスムーズに堂々と動きます:)



実際のところ、これで私の記事は終わり、それはあなたの想像のためだけに残っています。 この単純なメカニズム「多くの状態を定義する-各状態にオブジェクトのプロパティを割り当てる-状態間の遷移を決定する-遷移にアニメーションを設定する」を適用すると、印象的な結果を得ることができます。



そして、最後にいくつかの願いがあります。すべてが節度に優れていることを忘れないでください。 アニメーションでオーバーロードされたプログラムは、アニメーションがまったくないプログラムよりも使用するのがはるかに快適ではないため、取得した知識を利益のために使用してください:)



プロジェクトのソースコードはこちら (66 KB)にあります。



更新: 最初のプロジェクトに基づいて別の小さなプロジェクトを追加(368 KB、主に写真のため、これ以上コードはありません)。




All Articles