QTimer::singleShot 相当于 QML

问题描述 投票:0回答:6

考虑这个 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 代码启动,如果不可能使用单行代码,我会接受它作为答案。是吗?

qt qml
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()
        }
    }
} 

2
投票

我想到的另一个选择是简单地在 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!"))

在回调中您可以访问 QML 元素:

let abc = "Hello Luca!"
lqtUtils.singleShot(10000, function() {
    console.log(abc)
    myRect.color = "orange"
})
    
[...]
    
Rectangle {
    id: myRect
    anchors.fill: parent
    color: "red"
}

然后,我将该 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;重复:假;

    Timer {
      interval: 5000 
      running: true
      repeat: false
      onTriggered:console.log("Test");
    }
© www.soinside.com 2019 - 2024. All rights reserved.