2015-06-23 2 views
3

Рассмотрим следующий пример: у нас есть Qt Quick Controls Button. Пользователь нажимает его дважды в течение 5 секунд. После нажатия Button в первый раз QML Timer работает на эти 5 секунд. Мы хотим измерить время, прошедшее между двумя нажатиями, с точностью до миллисекунды.Измерение прошедшего времени в QML

К сожалению, QML Timer не может показать нам прошедшее время.

Как было предложено на форумах BlackBerry, можно было бы сравнить даты. Это не очень удобно, так как первый щелчок может появиться на 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.

Смежные вопросы