QTimer:: эквивалент singleShot для QML

Рассмотрим этот оператор С++ (пример из документации):

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, и я соглашусь с ним в качестве ответа, если однострочный шрифт невозможен. Это?

Ответ 1

Измените свойство "repeat" на false для объекта Timer.

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

Ответ 2

В итоге я добавил это в свой 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 () { ... } );

Ответ 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 action: scriptAction.script

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

Использование этого нового компонента дает то, что вы хотите:

SingleshotTimer { id: timer; delay: 60000; action: Qt.quit() }

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