[Qt-qml] Pause animation until a condition is met
Alex
alexlordax+qt at gmail.com
Fri Sep 10 20:32:04 CEST 2010
On Fri, Sep 3, 2010 at 9:16 AM, Adriano Rezende
<adriano.rezende at openbossa.org> wrote:
> Sorry, onConditionChanged is as follows:
>
> GuardAnimation.qml
> ===========================================
> ScriptAction {
> property variant target
> property bool condition
>
> script: if (condition) target.paused = true
> onConditionChanged: if (!condition) target.paused = false
> }
>
I've been doing some testing with this and ran into a couple of
problems, which are demonstrated by the code below. Please note that
I inverted the logic to suit my preferred usage and added logging.
GuardAnimation.qml
==================
import Qt 4.7
ScriptAction {
property string name
property variant target
property bool condition
script: {
if (!condition) {
console.log(name + ": pausing")
target.paused = true
}
}
onConditionChanged: {
if (condition) {
console.log(name + ": resuming")
target.paused = false
}
}
}
main.qml
=========
import Qt 4.7
Rectangle {
id: root
width: 200
height: 200
property int counter : 0
Timer {
interval: 1000; running: true; repeat: true
onTriggered: counter = (counter + 1) % 3
}
SequentialAnimation {
id: animation
running: true
ScriptAction { script: console.log("start of animation") }
GuardAnimation { name: "one"; target: animation; condition:
root.counter == 1 }
GuardAnimation { name: "two"; target: animation; condition:
root.counter == 2 }
ScriptAction { script: console.log("end of animation") }
}
}
Output
========
start of animation
one: pausing
two: pausing
end of animation
one: resuming
QAbstractAnimation::resume: Cannot resume an animation that is not paused
two: resuming
one: resuming
two: resuming
one: resuming
two: resuming
one: resuming
two: resuming
... etc
(1) There is a scoping issue - onConditionChanged continues to be
invoked long after the associated ScriptAction is stopped. This may
produce undesirable effects in those cases where there are multiple
guards. For example, in the case where there are two such guards, and
the second one is "executing," the onConditionChanged of the first
guard will get invoked if its condition is met, and resume the
animation prematurely. A variation on this problem is that an
explicitly paused animation may get implicitly resumed when a guard
condition is met.
(2) It looks like pausing, stopping, and resuming are not synchronous
operations. In the example above, you will see that the guards are
adjacent. They both attempt to pause the parent animation, but the
parent animation manages to run to completion before it is paused.
Here is the same test using my polling approach:
GuardAnimation.qml
==================
SequentialAnimation {
id: guardAnimation
property string name
property variant target // Not used
property bool condition
property bool firstIteration : true
loops: condition ? 0 : Animation.Infinite
ScriptAction {
script: {
if(firstIteration) {
console.log(name + ": pausing")
firstIteration = false
}
}
}
ScriptAction {
script: {
if(condition) {
console.log(name + ": resuming")
guardAnimation.running = false
}
}
}
PauseAnimation { duration: 200 }
}
Output
=======
start of animation
one: pausing
one: resuming
two: pausing
two: resuming
two: resuming
end of animation
Issue (2) is also apparent here (the second "two: resuming"), but the
result is harmless in this case.
Cheers,
Alex
PS: As an aside, just like I noted above about stop/pause/resume, it
seems that a property value changes are not synchronous. If I have
two adjacent ScriptAction blocks within an animation, with the first
one setting a property to a particular value and the second verifying
that the value has been set, the verification sometimes fails. If I
insert a PauseAnimation between the two ScriptActions, the
verification succeeds. I have been running into this with C++-derived
components, so perhaps this is not an issue in basic property types of
native QML components?
More information about the Qt-qml
mailing list