アニメーションフレームワークを使おう

Tips,PySide,PySide2,Python,Qt,MayaQPropertyAnimation

アニメーションフレームワークとはQObjetのプロパティを動的に変更することによって,ウィジェットやグラフィックスビューのアイテムやQObjectの任意のサブクラスで,アニメーション効果を利用できます。
簡単にいうとボタンやスライダーがウィンドウの端から動いて現れるようにするアニメーション効果を付けることができるのです!!
僕がよくScriptのUIを作るときに使うやつですね
今回は、「QPushButton」をベースに作成します

# -*- coding: utf-8 -*- 
import os
import sys

from Qt.QtWidgets import *
from Qt.QtGui import *
from Qt.QtCore import *
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

class GUI(MayaQWidgetBaseMixin, QMainWindow):
        def __init__(self, parent=None):
                super(GUI, self).__init__(parent)
                self.setGeometry(100, 300, 400, 300)
                self.setWindowTitle( "GUI" )
                self.initUI()

        def initUI(self):
            self.Button = QPushButton( "Button", self)

if __name__ == "__main__":
    app = QApplication.instance()
    main = GUI()
    main.show()
    sys.exit()
    app.exec_()

上のコードを実行すると下の画像のようなwindowが表示されるかと思います

次にボタンに対してアニメーションを追加したいので
アニメーションフレームワークに用意されているクラスQPropertyAnimationを使用します
QPropertyAnimationはQtのプロパティを動的に変更してアニメーションをさせることができるクラスです
QSequentialAnimationGroupとQParallelAnimationGroupは複数のアニメーションをつなぎ合わせ、並列に動作させることができ、これらのアニメーションがよく使われています。

「アニメーション」は、QPushButtonの"pos"プロパティを変化させて実現できます。
"pos"はそのオブジェクトの左上隅の位置を保持するQPoint型のプロパティです
最初に、QPropertyAnimation オブジェクトを定義します。
initUIに下のコードのようなQPropertyAnimationを追加します

def initUI(self):
    self.Button = QPushButton( "Button", self)
    self.ProAni = QPropertyAnimation( self.Button ,'pos', self )

これでself.Buttonの"pos"プロパティにアニメーションを付ける準備ができました。
後はアニメーションを付ける時間と開始/終了値の"pos"の値を定義します。

setDuration() アニメーションの動作時間
setStartValue() アニメーションの開始値
setEndValue() アニメーションの終了値

アニメーションの動作を制御するには上記の関数を定義する必要があります。
initUIにそれぞれを定義していきます。
今回は、動作時間を2秒に設定し開始値と終了値を設定してみます。

def initUI(self):
    self.Button = QPushButton( "Button", self)
    self.ProAni = QPropertyAnimation( self.Button ,'pos', self )
    self.ProAni.setDuration(2 * 1000)
    self.ProAni.setStartValue(QPoint(0,50))
    self.ProAni.setEndValue(QPoint(150,200))

上のコードを追加し、この状態でScriptを実行してみます。
しかし実行してみてもアニメーションが動くことはありません
というのも、アニメーションを動かすには"start()"を定義しなければならないためです。

def initUI(self):
    self.Button = QPushButton( "Button", self)
    self.ProAni = QPropertyAnimation( self.Button ,'pos', self )
    self.ProAni.setDuration(2 * 1000)
    self.ProAni.setStartValue(QPoint(0,50))
    self.ProAni.setEndValue(QPoint(150,200))
    self.ProAni.start()

上のコードのように"start()"を定義して実行すると下の画像のwindowのようにうまくボタンが動いたと思います

しかし、たんに一定速度で動かすだけではあじっけがありません。ここで少しスパイスを付けてみたいと思います。
"setStartValue()"と"setEndValue()"の代わりに"setKeyValueAt()"を用いて、第一引数で時間経過の割合を0.0から1.0の間の値で指定し,第二引数で対応する経過値を指定します。

def initUI(self):
    self.Button = QPushButton( "Button", self)
    self.ProAni = QPropertyAnimation( self.Button ,'pos', self )
    self.ProAni.setDuration(2 * 1000)
    self.ProAni.setKeyValueAt( 0.0, QPoint( 0, 50 ) )
    self.ProAni.setKeyValueAt( 0.5, QPoint( 200, 250 ) )
    self.ProAni.setKeyValueAt( 1.0, QPoint( 150, 200 ) )
    self.ProAni.start()

上のコードを実行すると下の画像のようにwindow内のボタンが素早く奥まで動きゆっくりと戻ってくると思います。

このように設定することでちょっとしたアクセントをつけることができ、UIに楽しさを追加することができます。
またこのほかに"setEasingCurve()"というものがあり、これによって加速度を考慮したアニメーションを実現することができます。
いったん、"setStartValue()"と"setEndValue()"で使用したコードを再び使い定義してみます。
今回は"OutBounce"を使ったコードを使用してみましょう

def initUI(self):
    self.Button = QPushButton( "Button", self)
    self.ProAni = QPropertyAnimation( self.Button ,'pos', self )
    self.ProAni.setDuration(2 * 1000)
    self.ProAni.setStartValue( QPoint( 0, 50 ) )
    self.ProAni.setEndValue( QPoint( 150, 200 ) )
    self.ProAni.setEasingCurve(QEasingCurve.OutBounce)
    self.ProAni.start()

上のコードを実行すると下の画像のようにwindow内のボタンがバウンドするような表現ができたかと思います

QEasingCurveは4つの加速原則の方法と10種類の保管曲線を組み合わせ、40種類あります。
それに加えLinearや、ユーザ定義のCustomがあります。

それらを駆使することでアニメーションをカスタムしてちょっと他とは違ったUIを作っていけます!
皆さんもこれらを使用していろんなアニメーションをが付いたGUIを作っていきましょう!!