Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create delay function in QML?

I would like to create a delay function in javascript that takes a parameter of amount of time to delay, so that I could use it do introduce delay between execution of JavaScript lines in my QML application. It would perhaps look like this:

function delay(delayTime) {   // code to create delay } 

I need the body of the function delay(). Note that setTimeout() of JavaScript doesn't work in QML.

like image 525
Sнаđошƒаӽ Avatar asked Feb 13 '15 19:02

Sнаđошƒаӽ


People also ask

How do I add a delay in QML?

Scheduler.qml Scheduler { id: scheduler; } scheduler. delay( function(){ console. log('Delayed'); }, 3000 );

How can you delay the execution of the function?

To delay a function call, use setTimeout() function. functionname − The function name for the function to be executed. milliseconds − The number of milliseconds. arg1, arg2, arg3 − These are the arguments passed to the function.

What is the use of QML in JavaScript?

QML supports the dynamic creation of objects from within JavaScript. This is useful to delay instantiation of objects until necessary, thereby improving application startup time. It also allows visual objects to be dynamically created and added to the scene in reaction to user input or other events.

How to dynamically load a QML component in Qt?

To dynamically load a component defined in a QML file, call the Qt.createComponent () function in the Qt object. This function takes the URL of the QML file as its only argument and creates a Component object from this URL. Once you have a Component, you can call its createObject () method to create an instance of the component.

How do I connect a QML signal to a JavaScript function?

Such scenarios can be handled by a signal connection. A signal emitted by a QML object may be connected to a JavaScript function by calling the signal's connect () method and passing the JavaScript function as an argument. For example, the following code connects the TapHandler 's tapped signal to the jsFunction () in script.js:

What are signal handler functions in QML?

QML object types can emit signals in reaction to certain events occurring. Those signals can be handled by signal handler functions, which can be defined by clients to implement custom program logic. Suppose that a button represented by a Rectangle type has a TapHandler and a Text label.


2 Answers

As suggested in the comments to your question, the Timer component is a good solution to this.

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(); 

The above would be how I'm currently using it, and here's how I might have implemented the example in your question.

function delay(delayTime) {     timer = new Timer();     timer.interval = delayTime;     timer.repeat = false;     timer.start(); } 

(Which doesn't do anything; read on)

Though the exact way you are looking for it to be implemented suggests that you are looking for it to block until the next line of your program executes. But this isn't a very good way to go about it as it would also block everything else in your program as JavaScript only runs in a single thread of execution.

An alternative is to pass a callback.

function delay(delayTime, cb) {     timer = new Timer();     timer.interval = delayTime;     timer.repeat = false;     timer.triggered.connect(cb);     timer.start(); } 

Which would allow you to use it as such.

delay(1000, function() {     print("I am called one second after I was started."); }); 

Hope it helps!

Edit: The above assumes you're working in a separate JavaScript file that you later import into your QML file. To do the equivalent in a QML file directly, you can do this.

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         })     } } 

I'm not convinced that this is the solution to your actual problem however; to delay an animation, you could use PauseAnimation.

like image 105
Marcus Ottosson Avatar answered Sep 18 '22 06:09

Marcus Ottosson


Marcus' answer does the job, but there is one big problem.

The problem is that the callback keeps connected to triggered signal even after triggered once. This means that if you use that delay function again, the timer will triggers all callbacks connected before again. So you should disconnect the callback after triggered.

This is my enhanced version of the delay function:

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); 
like image 34
Bumsik Kim Avatar answered Sep 21 '22 06:09

Bumsik Kim