2015-06-23 74 views
3

讓我們考慮下面的例子:我們有一個Qt Quick Controls Button。用戶在5秒內點擊兩次。在第一次推動Button之後,QML Timer正在運行這5秒鐘。我們想要測量兩次點擊之間的時間,精確到毫秒。用QML測量已用時間

不幸的是,QML Timer無法顯示已用時間。

根據黑莓論壇的建議,可以比較日期。但這不太方便,因爲第一次點擊可能發生在31 Dec 2015, 23:59:55上,第二次點擊可能發生在1 Jan 2016, 00:00:05上,並且檢查必須是複雜的。

有沒有更好的選擇?

回答

7

如評論中所述,QML Timer不適合您的特定需求,因爲它與動畫計時器同步(更多詳細信息,請參閱here),因此其分辨率也取決於動畫計時器。

@qCring解決方案確實令人滿意,如果需要更高的精度或更好的性能(另請參閱this answer以及底部關於提高精度的有趣鏈接),我更喜歡這種方法。

但是,根據您的要求,一個 QML/JS方法是完全可行的。在這種情況下,您可以利用JavaScript Date,因爲它是easy to calculate elapsed time,使用getTime(),但也因爲QML完全支持JS Date以及extends它具有一些有用的功能。

下面是一個簡單的例子:

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

不幸的是,QML Timer沒有提供屬性來檢查已用時間。但是,你可以寫你的自定義定時器C++和暴露在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(); 
}; 

通過qmlRegisterType<MyTimer>("MyStuff", 1, 0, "MyTimer")註冊後它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 
    } 
} 

希望這會有所幫助!

2

你不要在你的問題提如果測量時間是僅用於調試目的,或者它是否將需要其他計算。因爲如果QML不提供very simple way來調試使用console.time("id string")console.timeEnd("id string")進行各種操作的時間。

使用Button是這樣一個例子:

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

這將打印在毫秒的時間到控制檯,並且可以測量QML執行一些長時間操作所需要的時間是非常有用的。