HOWTO dynamically change animation limits when using States and Transitions
-
I would like to accomplish the following:
-
animate a displayed number from 0 to a random value
-
animate it back down to 0
-
briefly display a "—", then go back to start
In the code below, I have three States corresponding to the above cases:
- "idle": displays the "—".
- "on": displays the random number. Transition from "idle" to "on" should animate the display going up from 0.
- "off" displays 0. Transition from "on" to "off" should animate the display going down to 0. "off" to "idle" changes it back to a "—".
import QtQuick 2.0 Rectangle { id: root width: 400 height: 200 color: "LightGoldenRodYellow" Text { id: myText property int testVal: 0 property int maxVal // value to animate to? text: testVal.toString() anchors.centerIn: parent font.pointSize: 40 } state: "idle" states: [ State { name: "on" StateChangeScript { script: console.log("Entered on. maxVal = ") + myText.maxVal } PropertyChanges { target: myText; testVal: Math.floor(Math.random()*100) } }, State { name: "off" StateChangeScript { script: console.log("Entered off") } PropertyChanges { target: myText; testVal: 0.0 } // Reset to default props: testVal = 0 }, State { name: "idle" StateChangeScript { script: console.log("Entered idle") } // Override myText from "0" to mdash. BUT this needs to be a temporary // assignment in this state; everywhere else we want to preserve the testVal binding. PropertyChanges { target: myText; explicit: true; text: "—" } PropertyChanges { target: myText; maxVal: Math.floor(Math.random()*100) } } ] transitions: [ Transition { from: "idle"; to: "on" SequentialAnimation { // text was emdash, change to 0 //PropertyAction { target: myText; property: "text"; value: myText.testVal.toString() } //ScriptAction { script: console.log("Going idle -> on. maxVal = ") + myText.maxVal } NumberAnimation { //target: myText; property: "testVal"; to: myText.maxVal; duration: 1000; target: myText; property: "testVal"; duration: 1000; easing.type: Easing.InOutCubic } PauseAnimation { duration: 1000 } ScriptAction { script: root.state = "off" } } }, Transition { from: "on"; to: "off" SequentialAnimation { NumberAnimation { target: myText; property: "testVal"; duration: 1000; easing.type: Easing.InOutCubic } PauseAnimation { duration: 100 } ScriptAction { script: root.state = "idle"; } } }, Transition { from: "off"; to: "idle" SequentialAnimation { PauseAnimation { duration: 1000 } ScriptAction { script: root.state = "on"; } } } ] Component.onCompleted: { console.log("Starting FSM"); root.state = "on" } }
Based on my understanding of States and Transitions, the
explicit: true
in "idle" ought to temporarily assign the Text string to "—". Then I want to transition to "on". However, the animation limit in this transition needs to be set dynamically viaMath.random()
. I set this in thePropertyChanges
object corresponding to the "on" state, but this doesn't work. What I see happening is:- The "—" is displayed out of idle.
- The dash continues to be displayed in "on".
- The transition from "on" to "off" gets animated correctly from a random "on" value.
- The transition from "off" to "idle" also functions correctly.
Why does the idle --> on transition not work?
testVal
is 0 in idle.text
has been temporarily set to "—" but as soon as we transition out of idle, the defined binding oftext: testVal.toString()
should get restored. It is possible that the animation limit is not correctly calculated (because the value becomes known only in "on", but even so, I should have at least seen the text change from the dash to 0 at the exit out of idle.I have tried setting a separate
maxVal
property on the Text object and using that as the limit of the animation in the transition from "idle" to "on" (that value is calculated before the transition begins, so it should have avoided the problem noted above), but that didn't work either.Also tried to advance
root.state
as part of theStateChangeScript
in each state, but get the errorCan't apply a state change as part of a state definition.
How can I get this to work?
-