[Solved] States and timer not behaving as expected



  • A program I am building didn't work the way I expected so I tore it to pieces and made it much more modular. Unfortunately it still doesn't work but now it is more rationally organized I can extract the offending part and ask you for help.

    The UI is simply a text item with a mouse area and a controller. The controller is defined in a separate file and is simply a timer and three states.

    The desired behaviour is that it starts in the idle state waiting for a mouse click. When the user clicks the press me text it enters initDelay and sets the time interval and starts the timer. When the timer times out it enters the interval state sets the interval to a different value and enables the timer again. This last state should continue forever.

    What actually happens is that it all works untill the thrid state which it claims to enter but the next thing that happens is that the timer running property changes to false. The odd thing is that there is no obvious state transition to go with it.

    I'm quite new to this so I'm quite prepared to believe that I have missed something obvious, but what?

    Edit: I had forgotten the repeat property!
    Here is the code:
    ----Controller.qml
    @import QtQuick 1.1

    Item {
    state: "idle"

    function start(){
        state="initDelay"
    }
    onStateChanged: {
        console.log("State changed to " + state)
    }
    
    Timer{id:timer
        repeat: true // this was missing in the original, now it works as intended.
        onTriggered: {
            console.log("triggered")
            state="interval"
        }
        onRunningChanged: {
            console.log("running " + running)
        }
        onIntervalChanged: {
            console.log("interval " + interval)
        }
    }
    
    states: [
        State{
            name:"idle"
            PropertyChanges {
                target: timer
                running: false
            }
            StateChangeScript{
                name:"s1"
                script:{
                    console.log("entering " + name)
                }
            }
    
        },
        State{
            name:"initDelay"
            PropertyChanges {
                target: timer
                interval:4000
                running: true
            }
            StateChangeScript{
                name:"s2"
                script:{
                    console.log("entering " + name)
                }
            }
        },
        State{
            name:"interval"
            PropertyChanges {
                target: timer
                interval:1000
                running: true
            }
            StateChangeScript{
                name:"s3"
                script:{
                    console.log("entering " + name)
                }
            }
        }
    ]
    

    }
    @

    ----View.qml
    @
    import QtQuick 1.1

    Rectangle {
    width: 360
    height: 360
    Text {
    text: "Click me."
    MouseArea {
    anchors.fill: parent
    onClicked: {
    controller.start();
    }
    }
    }
    Controller{
    id:controller
    }
    }
    @



  • The running property of the Timer element changes to false, because it simply stops running after getting triggered. If you want to have the Timer element to trigger continuously until explicitly told to stop you need to set the "repeating" property of the Timer to true.



  • Damn! I actually did set repeating in the actual project, just forgot it in the code I posted.

    Now my cut down example works so I have to look for another bug in the real code.

    Thanks for the reminder. Having another pair of eyes look at a bug is much more effective than just staring at it again and again.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.