Home > Net >  How to trigger An Action Once After NumberAnimation Is Completed In QML
How to trigger An Action Once After NumberAnimation Is Completed In QML

Time:01-26

I am trying to call a reset function once after the animation is completed. But in the below given code , the animation starts after resetting the values

On Long press of the button I need to start an animation which basically acts as a progress bar, and once the animation is completed I need to call the reset() function.

I have tried the below given code , But here the animation starts once after the resetting of values are done.

Button {
    id: button1

    onPressAndHold: {
        rectangle.visible = true
        timer.restart()
    }
}

Item {
    id: rectangle

    Behavior on width {
        NumberAnimation {
            duration: 1000
            easing.type: Easing.InOutCubic
        }
    }
    Image {
        id: img
        source: "somesource"
        fillMode: Image.PreserveAspectCrop
    }
}

Timer {
    id: timer
    repeat: true
    interval: 50
    onTriggered: {
        rectangle.width = img.sourceSize.width * img.progress
        if (rectangle.width <= img.sourceSize.width) {
            timer.stop()
            reset(values)
        }
    }
}

can you please let me know on how modify it such that the animation completes first and then the reset is done. Thank you in advance!

CodePudding user response:

Ok, that really works for standalone Animation only that sounds a bit strange for me since the common usecase is using animations inside Behavior or State. So you can use NumberAnimation.onRunningChanged or ScriptAction as @iam_peter said or use Transition.onRunningChanged as well:

Window {
    height: 200
    width: 600
    visible: true
    title: qsTr("Animation test")

    RowLayout {
        width: parent.width
        height: 100
        anchors.centerIn: parent
        Button {
            text: "start"
            onClicked: {
                testRect.state = "state2"
            }
        }

        Rectangle {
            id: testContainer
            Layout.fillWidth: true
            Layout.fillHeight: true
            Rectangle {
                id: testRect
                height: 100
                width: 0
                color: "orange"

                states: [
                    State {
                        name: "state1"
                        PropertyChanges {
                            target: testRect
                            width: 0
                        }
                    },
                    State {
                        name: "state2"
                        PropertyChanges {
                            target: testRect
                            width: testContainer.width
                        }
                    }
                ]
                transitions: Transition {
                    NumberAnimation {
                        property: "width"
                        duration: 2000
                        easing.type: Easing.InQuad
                    }
                    onRunningChanged: {
                        if(running == false)
                        {
                            finishRect.color = "red";
                        }
                    }
                }
            }
        }
        Rectangle {
            id: finishRect
            Layout.preferredWidth: 100
            color: "yellow"
            width: 100
            height: width
            radius: width / 2
        }
    }
}

CodePudding user response:

According to this post you have two options.

You can us the onRunningChanged handler and check if the animation is still running. If not call anything you want at that point.

Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    Behavior on width {
        NumberAnimation {
            duration: 1000
            onRunningChanged: {
                if (!running)
                    console.log("Animation finished")
            }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: rect.width = 50
    }
}

The other option would be to create a SequentialAnimation and add a SrcriptAction that runs after the NumberAnimation is completed.

Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    Behavior on width {
        SequentialAnimation {
            NumberAnimation { duration: 1000 }
            ScriptAction {
                script: console.log("Animation finished")
            }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: rect.width = 50
    }
}
  • Related