Tuesday, March 22, 2011

Getting Animation start ,stop event in QML

While working on my hobby QML Project, I required to detect when particular animation got completed

Well its quite simple to achieve this but initially I struggled with it, I was trying to use onCompleted signal to detect animation end, but latter realised that it comes from component and not from animation.

Actual signal we want to use is onRunningChanged and we can check animation's running property to decide if animation is started or ended. Following is my sample QML code to detect Animation start and stop.
Behavior on rotation {
        PropertyAnimation {
            id: rotAni;
            duration: 500 ;
            onRunningChanged: {
                if (!rotAni.running) {
                    console.log("Animation completed");
                } else {
                    console.log("Animation started");
                }
            }
        }
    }
As requested in comment, I am posting similar example for NumberAnimation as well.
Rectangle {
        width: 360
        height: 360

        gradient:first
        Gradient {
            id:first
            GradientStop { position: 0.0; color: "red" }
            GradientStop { position: 0.33; color: "yellow" }
            GradientStop { position: 1.0; color: "green" }
        }
        Gradient {
            id:second
            GradientStop { position: 0.0; color: "red" }
        }

        MouseArea{
            anchors.fill:parent
            onClicked: {
                parent.gradient=second
                numAni.running = true;
            }
        }

        NumberAnimation{
            target:smallRect
            id:numAni
            properties: "x";
            to: 100;
            duration: 1000

            onRunningChanged:{
                if (!numAni.running) {
                    console.log("numAni Animation completed");
                } else {
                    console.log("numAni Animation started");
                }
            }
        }

        Rectangle{
            id:smallRect
            width:10;
            height:10;
        }
    }

6 comments:

  1. Interesting. I am trying to use your suggestion to make visible animations sequential. I have a javascript function, which call myModel.move() two times. I have a GridView to show myModel and I have "Behavior on x" animation, thus I can visualy see the movements. But, both movement animatons runs in paralell (the small delay between them is not noticeable).

    My idea was to add a counter of how many animations was started and how many of them already finished. Something like this;

    onRunningChanged: {
    if (animationX.running) {
    myModel.busy = myModel.busy + 1
    } else {
    myModel.busy = myModel.busy - 1
    }

    This works as expected. Then, I add a loop to my javascript function to wait until all the animations started.

    myModel.move(...)
    while (myModel.busy) {}
    myModel.move(...)

    Here is the problem. If I add some logging I can see that after the first move() all neccessary animations started, but nothing can be seen and none of the animation finished. I have some kind of a deadlock. How to solve this?

    ReplyDelete
  2. can you send your full code so i can tryout

    ReplyDelete
  3. does it work for NumberAnimation, SequentialAnimation, and ParallelAnimation?

    i've tried it, but it doesn't work..

    would you give me an example, please?

    ReplyDelete
    Replies
    1. I think it should work, but i will try my self and post example.

      Delete
    2. Hi,

      I tried it on NumberAnimation and it seems to work.

      Delete