Je souhaite créer une fonction de délai en javascript qui prend un paramètre de délai, de sorte que je puisse l'utiliser pour introduire un délai entre l'exécution des lignes JavaScript dans mon application QML. Cela ressemblerait peut-être à ceci:
function delay(delayTime) {
// code to create delay
}
J'ai besoin du corps de la fonction delay()
. Notez que setTimeout()
de javascript ne fonctionne pas dans QML.
Comme suggéré dans les commentaires de votre question, le composant Timer est une bonne solution à cela.
function Timer() {
return Qt.createQmlObject("import QtQuick 2.0; Timer {}", root);
}
timer = new Timer();
timer.interval = 1000;
timer.repeat = true;
timer.triggered.connect(function () {
print("I'm triggered once every second");
})
timer.start();
Ce qui précède serait la façon dont je l’utilise actuellement, et voici comment j’aurais pu implémenter l’exemple de votre question.
function delay(delayTime) {
timer = new Timer();
timer.interval = delayTime;
timer.repeat = false;
timer.start();
}
(Qui ne fait rien; lisez la suite)
Bien que la façon exacte dont vous cherchez à l'implémenter suggère que vous le cherchez pour bloquer jusqu'à l'exécution de la ligne suivante de votre programme. Mais ce n’est pas un très bon moyen de s’y prendre car cela bloquerait également tout le reste dans votre programme, car JavaScript ne fonctionne que dans un seul thread d’exécution.
Une alternative consiste à passer un rappel.
function delay(delayTime, cb) {
timer = new Timer();
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
Ce qui vous permettrait de l'utiliser comme tel.
delay(1000, function() {
print("I am called one second after I was started.");
});
J'espère que ça aide!
Edit: Ce qui précède suppose que vous travaillez dans un fichier JavaScript séparé que vous importerez ultérieurement dans votre fichier QML. Pour faire l'équivalent dans un fichier QML directement, vous pouvez le faire.
import QtQuick 2.0
Rectangle {
width: 800
height: 600
color: "brown"
Timer {
id: timer
}
function delay(delayTime, cb) {
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
Rectangle {
id: rectangle
color: "yellow"
anchors.fill: parent
anchors.margins: 100
opacity: 0
Behavior on opacity {
NumberAnimation {
duration: 500
}
}
}
Component.onCompleted: {
print("I'm printed right away..")
delay(1000, function() {
print("And I'm printed after 1 second!")
rectangle.opacity = 1
})
}
}
Je ne suis cependant pas convaincu que ce soit la solution à votre problème actuel; pour retarder une animation, vous pouvez utiliser PauseAnimation .
La réponse de Marcus fait le travail, mais il y a un gros problème .
Le problème est que le rappel reste connecté au signal triggered
même après avoir été déclenché une fois. Cela signifie que si vous utilisez à nouveau cette fonction de délai, la minuterie déclenchera les rappels tous connectés avant. Vous devez donc déconnecter le rappel après avoir été déclenché.
Voici ma version améliorée de la fonction delay:
Timer {
id: timer
function setTimeout(cb, delayTime) {
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.triggered.connect(function release () {
timer.triggered.disconnect(cb); // This is important
timer.triggered.disconnect(release); // This is important as well
});
timer.start();
}
}
...
timer.setTimeout(function(){ console.log("triggered"); }, 1000);
vous pouvez utiliser QtTest
import QtTest 1.0
import QtQuick 2.9
ApplicationWindow{
id: window
TestEvent {
id: test
}
function delay_ms(delay_time) {
test.mouseClick(window, 0, 0, Qt.NoButton, Qt.NoModifier, delay_time)
}
}