Change state after transition animation finishes

I want to change the state after the transition animation has finished. I have the following code that achieves this, although it looks hackish:

import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2

Rectangle {
    id: root
    width: 400
    height: 400

    Rectangle {
        id: rect
        color: "blue"
        width: 50
        height: 50
        anchors.centerIn: parent

        MouseArea {
            anchors.fill: parent
            onClicked: rect.state = "animating"
        }

        states: [
            State {
                name: "animating"

                PropertyChanges {
                    target: rect
                    rotation: 360
                }
            },
            State {
                name: "shrinking"

                PropertyChanges {
                    target: rect
                    scale: 0
                }
            }
        ]

        transitions: [
            Transition {
                from: ""
                to: "animating"

                SequentialAnimation {
                    RotationAnimation {
                        duration: 500
                    }
                    ScriptAction {
                        script: rect.state = "shrinking"
                    }
                }
            },
            Transition {
                from: "animating"
                to: "shrinking"

                NumberAnimation {
                    property: "scale"
                    duration: 500
                }
            }
        ]
    }
}

      

Is there a better way to do this without using ScriptAction

? Note that I need the second state, and I don't want to just consolidate the scale animation into the SequentialAnimation

transition animating

.

+3


source to share


2 answers


The correct way is to change the state in the runningChanged

transition handler when it transitions to false, which completes the animation. for this you have two solutions:

Sol 1.use connections

(you will get a warning about some notifiable property, ignore it)

Connections{
            target:rect.transitions[0]

            onRunningChanged:{
                if( rect.transitions[0].running === false)
                {
                    rect.state = "shrinking"
                }
            }
        }

      

the code will be:



import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2

Rectangle {
    id: root
    width: 400
    height: 400

    Rectangle {
        id: rect
        color: "blue"
        width: 50
        height: 50
        anchors.centerIn: parent

        MouseArea {
            anchors.fill: parent
            onClicked: rect.state = "animating"
        }

        states: [
            State {
                name: "animating"

                PropertyChanges {
                    target: rect
                    rotation: 360
                }
            },
            State {
                name: "shrinking"

                PropertyChanges {
                    target: rect
                    scale: 0
                }
            }
        ]
        Connections{
            target:rect.transitions[0]

            onRunningChanged:{
                if( rect.transitions[0].running === false)
                {
                    rect.state = "shrinking"
                }
            }
        }
        transitions: [
            Transition {
                from: ""
                to: "animating"
                    RotationAnimation {
                        duration: 500
                    }
            },
            Transition {
                from: "animating"
                to: "shrinking"

                NumberAnimation {
                    property: "scale"
                    duration: 500
                }
            }
        ]
    }
}

      

solution 2: change state in handler runningChanged

directly on transition:

import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2

Rectangle {
    id: root
    width: 400
    height: 400

    Rectangle {
        id: rect
        color: "blue"
        width: 50
        height: 50
        anchors.centerIn: parent

        MouseArea {
            anchors.fill: parent
            onClicked: rect.state = "animating"
        }

        states: [
            State {
                name: "animating"

                PropertyChanges {
                    target: rect
                    rotation: 360
                }
            },
            State {
                name: "shrinking"

                PropertyChanges {
                    target: rect
                    scale: 0
                }
            }
        ]

        transitions: [
            Transition {
                from: ""
                to: "animating"

                    RotationAnimation {
                        duration: 500
                    }
                    onRunningChanged:{
                        if( running === false)
                        {
                            rect.state = "shrinking"
                        }
                    }
            },
            Transition {
                from: "animating"
                to: "shrinking"

                NumberAnimation {
                    property: "scale"
                    duration: 500
                }
            }
        ]
    }
}

      

I prefer the first solution ( connections

) because it is more general

0


source


A slightly different approach is to set state shrinking

to state animating

and use it PropertyAction

to force a state change at the end of the transition:

        State {
            name: "animating"

            PropertyChanges {
                target: rect
                rotation: 360
            }
            PropertyChanges {
                target: rect
                state: "shrinking"
            }

      

and



        Transition {
            SequentialAnimation {
                RotationAnimation {
                    duration: 500
                }
                PropertyAction {
                    target: rect
                    property: "state"
                }
            }
        }

      

Note that I agree with jturcotte on his assessment of the use of these states here.

-1


source







All Articles