【问题标题】:Measuring elapsed time in QML在 QML 中测量经过的时间
【发布时间】:2015-06-23 08:03:08
【问题描述】:

让我们考虑以下示例:我们有一个 Qt Quick Controls Button。用户在 5 秒内点击了两次。在第一次推送Button 后,QML Timer 运行了这 5 秒。我们想要测量两次点击之间经过的时间,精确到毫秒。

很遗憾,QML Timer 无法向我们显示经过的时间。

按照 BlackBerry 论坛上的建议,可以比较日期。不过,这不是很方便,因为第一次点击可能发生在31 Dec 2015, 23:59:55 上,第二次点击可能发生在1 Jan 2016, 00:00:05 上,而且检查必须很复杂。

还有更好的选择吗?

【问题讨论】:

    标签: qt time qml qtquick2 qt-quick


    【解决方案1】:

    如 cmets 中所述,QML Timer 不适合您的特定需求,因为它与动画计时器同步(更多详细信息here),因此其分辨率也取决于动画计时器。

    @qCring 解决方案肯定令人满意,如果需要更高的精度或更好的性能,我更喜欢这种方法(另请参阅this answer 和底部关于提高精度的有趣链接)。

    但是,鉴于您的要求, QML/JS 方法是完全可行的。在这种情况下,您可以利用 JavaScript Date,这既是因为它是 easy to calculate elapsed time,使用 getTime(),还因为 QML 完全支持 JS Dateextends,它具有一些有用的功能。

    这是一个简单的例子:

    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】:

      如果测量的时间仅用于调试目的,或者是否需要用于其他计算,您没有在问题中提及。因为如果不是,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 中执行一些长时间操作所需的时间非常有用。

      【讨论】:

        【解决方案3】:

        不幸的是,QML Timer 没有提供检查经过时间的属性。但是你可以用 C++ 编写你的自定义 Timer 并将它暴露给 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&lt;MyTimer&gt;("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
            }
        }
        

        希望这会有所帮助!

        【讨论】:

          猜你喜欢
          • 2014-09-05
          • 2011-11-17
          • 1970-01-01
          • 2013-03-17
          • 1970-01-01
          • 1970-01-01
          • 2017-07-13
          • 2019-12-30
          相关资源
          最近更新 更多