Aiyyaa
Aiyyaa

Reputation: 85

Qml function with Timer works wrong

I have a QML project, there I have a Timer class. When I run code, there is just white window without anything. I expected what when I press "Up" button, there is a yellow rectangle showed for 5 seconds, and on this rectangle will be written number "5" for 1 second, then "4" for 1 second and so on and after 5 seconds this rectangle will disappear.

But my code works differently, and I really confused.

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
   visible: true
   width: 640
   height: 480

   Timer {
        id: timer
        function setTimeout(cb, delayTime) { 
            timer.interval = delayTime;
            timer.repeat = true;
            timer.triggered.connect(cb);
            timer.start();
        }
    }

    Rectangle{ // This is invisible rectangle 
        width: 100
        height: 100
        focus: true 
        Keys.onPressed: { //
            if (event.key == Qt.Key_Up){ // this is function where I change values of number
                console.log(tf.counter); //this is for debugging 
                tf.counter = 5; // tf is id of Text
                test.visible = true; // test is id of yellow rectangle
                timer.setTimeout(function(){ //setTimeout is function defined in Timer
                    tf.counter--;
                    if (tf.counter > 0){
                        tf.text = tf.counter;
                    }
                    else {
                        tf.counter = 5;
                        tf.text = tf.counter;
                        test.visible = false;
                        timer.stop();
                    }
                
                }, 1000);
            }
        }
    
    }

    Rectangle{
    
        id: test 
        visible: false // now this is invisible
        color:  "yellow"
        width: 100
        height: 100
        x: 200
        y: 200
    
        Text {
            x: 5
            y: 5
            property int counter: 5 // this is custom property which I assign to tf.text 
            id: tf
            text: "5"
        }
    }
}

When I press "Up" button for the first time, it works totally fine, but then I press "Up" for the second time and after that it works so weird, I don't understand why. In second time, it gives me "5", then "3", then "1". In third time, it gives me "4", "1". And then my rectangle shows only for one second and there is always random number on it. Please help me. I tried really hard on solving why this code doesn't work properly.

Upvotes: 2

Views: 2045

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

You are complicating with logic, if the following rules are established, the logic is simple:

  1. When you press the Up key, you must start the timer and make the Rect visible.

  2. Each time a second elapses with the Timer, the counter is decreased by 1.

  3. When the counter reaches 0, the timer must be stopped, the Rect invisible and the counter set to 0 again.

*.qml

Window {
    visible: true
    width: 640
    height: 480
    Timer {
        id: timer
        onTriggered: tf.counter--; // 2
        interval: 1000
        repeat: true
    }
    Rectangle{ // This is invisible rectangle
        width: 100
        height: 100
        focus: true
        Keys.onPressed: if (event.key === Qt.Key_Up){rect.visible = true; timer.start()} // 1
    }
    Rectangle{
        id: rect
        visible: false
        color:  "yellow"
        width: 100
        height: 100
        x: 200
        y: 200
        Text {
            id: tf
            x: 5
            y: 5
            property int counter: 5
            onCounterChanged: if(counter == 0){rect.visible = false; timer.stop(); counter=5} // 3
            text: counter
        }
    }
}

Another solution:

Window {
    visible: true
    width: 640
    height: 480
    Timer {
        id: timer
        onTriggered: tf.counter--;
        interval: 1000
        repeat: true
        running: tf.counter > 0
    }
    Rectangle{ // This is invisible rectangle
        width: 100
        height: 100
        focus: true
        Keys.onPressed: if (event.key === Qt.Key_Up && !timer.running){tf.counter = 5}
    }
    Rectangle{
        id: rect
        visible: timer.running
        color:  "yellow"
        width: 100
        height: 100
        x: 200
        y: 200
        Text {
            x: 5
            y: 5
            property int counter: 0
            id: tf
            text: counter
        }
    }
}

Upvotes: 2

Related Questions