Reputation: 85
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
Reputation: 243897
You are complicating with logic, if the following rules are established, the logic is simple:
When you press the Up key, you must start the timer and make the Rect visible.
Each time a second elapses with the Timer, the counter is decreased by 1.
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