I'm trying to implement a fitness application that displays the current exercise name then shows a progress bar during the resting periods. When the progress bar is fully filled, the name of the next exercise is displayed, then a progress bar is shown when it is completed, and so on.
Note that I'm using a progress bar for this example but I'll have my own widget in the real application.
My system has two states :
So it goes like this :
My issue is with step 5 : I do not know how to switch back to another state at the end of a transition. I've tried to change the "state" property during a PropertyChanges and time it at the end of a transition with a SequentialAnimation, but I get this error message :
QML StateGroup: Can't apply a state change as part of a state definition.
Here is some sample code :
import QtQuick 2.0
import QtQuick.Controls 1.1
ProgressBar {
id: root
width: 200
height: 48
minimumValue: 0
maximumValue: 100
value: 76
function switchState() {
if (state == "exercise")
{
state = "rest"
return
}
if (state == "rest")
{
state = "exercise"
return
}
}
state: "exercise"
states: [
State {
name: "exercise"
PropertyChanges {
target: root
value: 0
}
},
State {
name: "rest"
PropertyChanges {
target: root
value: maximumValue
// error: QML StateGroup: Can't apply a state change as part of a state definition.
// state: "exercise"
}
}
]
transitions: [
Transition {
to: "rest"
PropertyAnimation {
target: root
properties: "value"
duration: 1000
}
}
]
MouseArea {
anchors.fill: parent
onClicked: parent.switchState()
}
}
How can I switch to another state at the end of a state transition ?
I believe you can do this by using the RunningChanged signal from the transition:
transitions: [
Transition {
to: "rest"
PropertyAnimation {
target: root
properties: "value"
duration: 1000
}
onRunningChanged: {
if ((state == "rest") && (!running))
switchState();
}
}
]
QML Objects have an associated signal for property changes (on<Property>Changed
). The associated handlers are usually not documented in the objects' references, but are implicitly available due to the property's existence. See this.
UPDATE
I proposed a wrong solution because a mistake, so excuse me please.
Fixing its problem results same solution as @GabrielF one. So I deleted it to avoid repeating.
However below solution works great and gives you fine control within a Transition/Animaiton.
Also another way!
transitions: [
Transition {
to: "rest"
SequentialAnimation {
PropertyAnimation {
target: root
properties: "value"
duration: 1000
}
ScriptAction { script: switchState() } //<----
}
}
]
Please note that with SequentialAnimation
within a transition animation, you don't need to define a middle state, if you like to just ensure that an specific animation is completed.
Goodluck - S.M.Mousavi
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With