问题
Let's consider the following example: we have a Qt Quick Controls Button
. The user clicks it twice within 5 seconds. After pushing the Button
for the first time, the QML Timer
is running for these 5 seconds. We want to measure the time elapsed between two clicks, with a millisecond accuracy.
Unfortunately, the QML Timer
can't show us the elapsed time.
As suggested on the BlackBerry forums, it would be possible to compare the dates. This isn't very handy, though, since the first click might occur on 31 Dec 2015, 23:59:55
and the second on 1 Jan 2016, 00:00:05
and the check would have to be complex.
Is there any better option?
回答1:
As explained in the comments, QML Timer
is not suitable for your specific needs since it is synchronized with the animation timer (further details here) and thus its resolution is dependent on animation timer as well.
@qCring solution is for sure satisfying and I would prefer such an approach, if an higher precision is needed or a better performance (see also this answer and the interesting link at the bottom about improving precision).
However, given your requirements, a pure QML/JS approach is perfectly feasible. In this case you can exploit JavaScript Date
, both because it's easy to calculate elapsed time, using getTime(), but also because QML fully supports JS Date
and also extends it with some useful functions.
Here is 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
}
}
}
}
}
回答2:
Unfortunately, the QML Timer
doesn't provide a property to check the elapsed time. But you could write your custom Timer in C++ and expose it to 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 registering via qmlRegisterType<MyTimer>("MyStuff", 1, 0, "MyTimer")
it's 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!
回答3:
You don't mention in your question if the measured time is only for debugging purposes or if it will be needed for other calculations. Because if not QML offers a very simple way to debug the time spent doing various operations using console.time("id string")
and console.timeEnd("id string")
.
An example using a 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 ms to the console, and can be very useful to measure the time needed to execute some long operations in QML.
来源:https://stackoverflow.com/questions/30997134/measuring-elapsed-time-in-qml