QML的QTimer::singleShot等效方法是什么?

16

考虑下面这个C++语句(来自文档示例):

QTimer::singleShot(600000, &app, SLOT(quit()));

如何在.qml JavaScript中执行相同的操作,类似于以下QML代码:

Rectangle {
    property int counter: 0
    onCounterChanged: {
        if (counter > 42) {
            // do equivalent of above C++ statement here
        }
    }
    // more code, which actually manipulates counter 
}

有一个显而易见的解决方案,就是使用单独的Timer,然后由这段JavaScript代码启动。如果无法在一行内解决,我将接受该答案。是否可以?


2
相当的功能是Timer。将repeat: false设置为单次触发行为。 - Pavel Strakhov
1
默认情况下,repeatfalse - hyde
1
不错的问题。setTimeout/setInterval 不可用,可以考虑使用 这个答案 - 一种相当 hackish 的方法。通过在函数签名中设置参数,可以将使用减少到一行,例如 delay(/*repeat*/ true, 12000, functionName) - BaCaRoZzo
6个回答

14

我最终将这个添加到了我的 main.qml 文件中:

Component {
    id: delayCallerComponent
    Timer {
    }
}

function delayCall( interval, callback ) {
    var delayCaller = delayCallerComponent.createObject( null, { "interval": interval } );
    delayCaller.triggered.connect( function () {
        callback();
        delayCaller.destroy();
    } );
    delayCaller.start();
}

可以像这样使用:

delayCall( 1000, function () { ... } );

12

将 Timer 对象的 "repeat" 属性改为 false。

import QtQuick 1.0

Item {
    Timer {
        id: timer
        interval: 600000
        running: false
        repeat: false
        onTriggered: Qt.quit()
    }

    Rectangle {
        property int counter: 0
        onCounterChanged: {
            if (counter > 42) {
                timer.running = true
            }
        }
    }
}

3

使用SequentialAnimation元素来实现如下:

SequentialAnimation {
    id: quitTimer
    PauseAnimation { duration: 60000 }
    ScriptAction { script: Qt.quit() }
}

Rectangle {
    property int counter: 0
    onCounterChanged: {
        if (counter > 42) {
            quitTimer.start()
        }
    }
}

如果那看起来太难看,可以将其制作成组件:
// SingleshotTimer.qml
import QtQuick 2.0
SequentialAnimation {
    property alias delay: delayAnim.duration
    property alias script: scriptAction.script

    PauseAnimation { id: delayAnim; duration: 10000 }
    ScriptAction { id: scriptAction }
}

使用这个新组件可以得到你想要的结果:
SingleshotTimer { id: timer; delay: 60000; script: Qt.quit() }

Rectangle {
    property int counter: 0
    onCounterChanged: {
        if (counter > 42) {
            timer.start()
        }
    }
} 

1

我想到的另一个选项是在C++中简单地定义如下函数:

void QmlUtils::singleShot(int msec, QJSValue callback)
{
    QTimer::singleShot(msec, this, [callback] () mutable {
        if (callback.isCallable())
            callback.call();
    });
}

我称之为QML中调用:

lqtUtils.singleShot(5000, () => console.log("Hello!"))

然后,我将这个C++函数添加到我的“必备”收藏夹中:https://github.com/carlonluca/lqtutils/blob/master/lqtutils_ui.h#L53


1

在QML中有一个计时器组件。

import QtQuick 2.0

Item {
    Timer {
        interval: 500; running: true; repeat: true
        onTriggered: time.text = Date().toString()
    }

    Text { id: time }
}

更多细节请查看文档:查看文档

0

我设置属性如下:running: true; repeat: false;

    Timer {
      interval: 5000 
      running: true
      repeat: false
      onTriggered:console.log("Test");
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接