QMLの状態変化とアニメーション効果
QML State and Animation
QMLアイテムにアニメーション効果を適用したい場合は、transitionsプロパティを使用します。
Transitionを定義する前に、アニメーション後の状態を示すコードを用意します。この状態はstatesプロパティーで記述し、State.nameで指定した名称をアイテムのstateプロパティに代入すると、State内の定義がアイテムに反映されるようになります。アイテムのステータスの変更を検知したいのであれば「onStateChanged」関数を組み込みます。
Stateに定義できものとして、アンカーを変更する「AnchorChanges」、アイテムの親子関係を変更する「ParentChange」、アイテムのプロパティを変更する「PropertyChanges」が挙げられます。
Stateによるプロパティ値の変更例を紹介します。このQMLコードでは、ボタンを押すと「lblColor.state」が「red」に設定されます。これによりラベルのstatesにある「red」を名称に持つデータが適用されるため、lblColorをターゲットにcolorプロパティが"red"になります。なお、「target:this」と記述してしまうとStateアイテムを参照することになるため、この方法は使えません。
state.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("State test")
ColumnLayout{
Label{
id: lblColor
text: "Hello!"
state: "black"
states:[
State{
name:"black"
PropertyChanges{
target:lblColor
color:"black"
}
},
State{
name:"red"
PropertyChanges{
target:lblColor
color:"red"
}
}
]
}
Button{
text: "Change"
onClicked: {
lblColor.state = "red";
}
}
}
}
Stateにある「when」プロパティがtrueであるときは、そのステータスが自動で適用されます。つまり、whenに条件式を割り当てれば、シグナルを調べる必要がなくなるというわけです。
when.qml
MouseArea{
id:ma
states:[
State{
// このマウスエリアが押されると、rcというアイテムが表示される
when: ma.pressed
PropertyChanges {
target: rc
visible: true
}
}
]
}
アイテムのtransitionsプロパティ内に記述することで、stateをキーにしたアニメーションを実行できます。
この例では、ラベルのステートが"black"から"red"に切り替わった時に、ColorAnimationが実行されるので、1秒かけて文字の色が黒から赤に変わっていきます。
color.qml
Label{
id: lblColor
text: "Hello!"
state: "black"
states:[
State{
name:"black"
PropertyChanges{
target:lblColor
color:"black"
}
},
State{
name:"red"
PropertyChanges{
target:lblColor
color:"red"
}
}
]
transitions: [
Transition {
from: "black"
to: "red"
ColorAnimation {
target:lblColor
duration: 1000
}
}
]
}
transitionsは配列なので、状態値の変化の数だけTransitionを追加できます。また、fromを明示しない場合は、変化前のstateはすべての値が対象になります。toも同様です。
次にアイテムのプロパティ値を徐々に変化させることでアニメーションさせる「PropertyAnimation」について解説します。このデータの「property」に指定したプロパティ
文字列(クォーテーションで囲まないとそのプロパティの数値が参照されてしまうため動作しない)を「from(未指定の場合は現時点のアイテムが持つ値)」から「to」へとdurationミリ秒をかけて変化していきます。easingプロパティによるイージングも実装できます。
move.qml
ColumnLayout{
Label{
id: lblColor
/* 省略 */
transitions: [
Transition {
from: "black"
to: "red"
ColorAnimation {
target:lblColor
duration: 1000
}
},
Transition{
to: "move"
PropertyAnimation {
target: lblColor
// 複数のターゲットを指定したい場合の例
// targets:[lblColor, lblExtra]
easing.type: Easing.InOutQuad
to: 200
duration: 2000
property: "x"
// 複数のプロパティを同時に変更したい場合の例
// properties: "x,y"
to: 200
}
}
]
}
Button{
text: "Color"
onClicked: {
lblColor.state = "red";
}
}
Button{
text: "Move"
onClicked: {
lblColor.state = "move";
}
}
}
このコードでは「Move」ボタンを押すとラベルのステートが「move」になり、かつfromステートが未指定なので、ラベルの状態(stateがblackかredであるか)に関わらず、ラベルが右方向に200ピクセル移動します。
対象のプロパティが数値型であれば、PropertyAnimationの代わりにNumberAnimationを使うことができます。基本的な動作は変わりありませんが、数値に特化した分、処理は高速です。
number.qml
Transition{
to: "move"
NumberAnimation {
target: lblColor
property: "x"
easing.type: Easing.InOutQuad
to: 200
duration: 2000
}
}
2018/10/30