11

I have several states which I use only to change some properties:

Item {
    id: props
    property int someProperty: 0
    // ...

    states: [
        State {
            name: "firstState"
            PropertyChange {
                target: props
                someProperty: 1
                // ...
            }
        },
        State {
            name: "secondState"
            PropertyChange {
                target: props
                someProperty: 1
                // ...
            }
        }
    ]
    onStateChange: doSomething(someProperty)
}

Since different states could have the same value for someProperty I can't rely on the somePropertyChange signal, but I can't even rely on the onStateChange (as in the example) since when it runs the properties are unchanged.

So how could I run doSomething() every time the state change? There is a better way to do this kind of things with QML?

4
  • Where did you run the command that a state should change? There you can also execute your "doSomething()" method. Furthermore you can use property bindings for changing properties - that is the better way. QML is a declarative language! Commented Nov 19, 2015 at 13:29
  • @sk2212 I run the command for state change in several parts trough the application so putting doSomething() everywhere doesn't sound like a good choice (but I could create a function that change state and run doSomething() instead of changing the value of state). In the real application someProperty is the number of seconds after which an event should be triggered, if the state change the timer should start from the beginning (if two states have the same number of seconds the somePropertyChange signal is not fired so the timer doesn't restart by using a property binding). Commented Nov 19, 2015 at 21:03
  • Well...how do you change the state through your application? Referencing the id in other qml files? Maybe you should also have a look in running property from Timer component. Commented Nov 20, 2015 at 7:57
  • the state is changed in "many" parts of the same qml file. The problem at hand is that I need to restart a Timer when the state change even if the value of the seconds is exactly the same. Commented Nov 23, 2015 at 7:54

2 Answers 2

12

You can run some script using StateChangeScript.

Item {
    id: props
    property int someProperty: 0

    states: [
        State {
            name: "firstState"
            PropertyChanges {
                target: props
                someProperty: 1
            }
            StateChangeScript {
                name: "firstScript"
                script: console.log("entering first state")
            }
        },
        State {
            name: "secondState"
            PropertyChanges {
                target: props
                someProperty: 1
            }
            StateChangeScript {
                name: "secondScript"
                script: console.log("entering second state")
            }
        }
    ]
}
Sign up to request clarification or add additional context in comments.

2 Comments

but with this solution I need to place a StateChangeScript inside every State
Doesn't seem like a huge issue to me... but if you're really worried about that, you can create your own State item, which would already include a StateChangeScript. Tweak the default property in that custom state to manage the order of operations yourself, and you're good to go.
1
Item {
    id: props
    property int someProperty: 0
    // ...

    states: [
        State {
            name: "firstState"
            PropertyChange {
                target: props
                someProperty: 1
                // ...
            }
        },
        State {
            name: "secondState"
            PropertyChange {
                target: props
                someProperty: 1
                // ...
            }
        }
    ]

    transitions: [
        Transition {
            ScriptAction { 
                script: console.log("transition to " + props.state) 
            }
        }
    ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.