Measuring Elapsed Time in QML

Consider the following example: we have Qt Quick Controls Button

. The user presses it twice within 5 seconds. After clicking Button

for the first time, QML Timer

works for those 5 seconds. We want to measure the elapsed time between two clicks with millisecond precision.

Unfortunately, QML Timer

cannot show us the past tense.

As suggested in the BlackBerry forums, one would compare the dates. This is not very convenient, since the first click may appear on 31 Dec 2015, 23:59:55

, and the second on 1 Jan 2016, 00:00:05

, and the check should be difficult.

Is there a better option?

+6


source to share


3 answers


As explained in the comments, QML is Timer

not suitable for your specific needs as it syncs with the animation timer (more details here ) and hence its resolution also depends on the animation timer.

@QCring's solution is for sure satisfactory and I would prefer this approach if higher precision or better performance is required (see also this answer and the interesting link below on improving precision).

However, given your requirements, a pure QML / JS approach is perfectly feasible. In this case, you can use JavaScript Date

because it is easy to calculate the elapsed time using getTime()

and also because QML fully supports JS Date

and also extends it with some useful features.



Here's a simple example:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.3

ApplicationWindow {
    width: 300
    height: 300
    visible: true

    property double startTime: 0

    ColumnLayout {
        anchors.fill: parent

        Text {
            id: time
            font.pixelSize: 30
            text: "--"
            Layout.alignment: Qt.AlignCenter
        }

        Button {
            text: "Click me!"
            Layout.alignment: Qt.AlignCenter

            onClicked: {
                if(startTime == 0){
                    time.text = "click again..."
                    startTime = new Date().getTime()
                } else {
                    time.text = new Date().getTime() - startTime + " ms"
                    startTime = 0
                }
            }
        }
    }
} 

      

+12


source


Unfortunately, QML Timer

does not provide properties for checking the elapsed time. But you can write your own timer in C ++ and expose it in QML:

MyTimer.h

#include <QObject>
#include <QElapsedTimer>

class MyTimer : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int elapsed MEMBER m_elapsed NOTIFY elapsedChanged)
    Q_PROPERTY(bool running MEMBER m_running NOTIFY runningChanged)
private:
    QElapsedTimer m_timer;
    int m_elapsed;
    bool m_running;
public slots:
    void start() {
        this->m_elapsed = 0;
        this->m_running = true;

        m_timer.start();
        emit runningChanged();
    }

    void stop() {
        this->m_elapsed = m_timer.elapsed();
        this->m_running = false;

        emit elapsedChanged();
        emit runningChanged();
    }

signals:
    void runningChanged();
    void elapsedChanged();
};

      

After registration via qmlRegisterType<MyTimer>("MyStuff", 1, 0, "MyTimer")

it is available in QML:



Window.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import MyStuff 1.0

ApplicationWindow {
    width: 800
    height: 600
    visible: true

    Button {
        id: button
        anchors.centerIn: parent
        text: timer.running ? "stop" : "start"
        checkable: true

        onClicked: {
            if (timer.running) {
                timer.stop()
                label.text = timer.elapsed + "ms"
            } else { 
                timer.start()
            }
        }

        MyTimer {
            id: timer
        }
    }

    Text {
        id: label
        anchors.left: button.right
        anchors.verticalCenter: button.verticalCenter
        text: "0ms"
        visible: !timer.running
    }
}

      

Hope this helps!

+5


source


You haven't mentioned in your question if the measured time is for debugging purposes only, or if it will be required for other calculations. Because if QML doesn't offer a very easy way to debug the time spent performing various operations using console.time("id string")

and console.timeEnd("id string")

.

An example using Button

would look like this:

Button {
    text: "click here"
    property bool measuring: false
    onClicked: {
        if(!measuring){
            console.time("button")
            measuring=true
        } else {
            console.timeEnd("button")
            measuring=false
        }
    }
}

      

This will print the time in milliseconds to the console and can be very useful for measuring the time it takes to perform some lengthy operations in QML.

+4


source







All Articles