Qml定时器与匿名函数

2023-03-17 15:26:12 浏览数 (3)

  本文介绍如何使用Qml定时器与js的匿名函数的结合,解决定时器的繁杂操作。

  Qml使用定时器一般是这样的:

代码语言:javascript复制
Timer {
    interval: 1000
    running: true
    onTriggered: { 
        /* dosomething */
    }
}

  但如果有多个定时器任务,则需要创建多个Timer对象,而这些对象没有销毁,导致内存长期占用。特别是那些只执行一次的定时器。

  如果Qml使用定时器能像Qt下面代码一样使用定时器多好啊。

代码语言:javascript复制
QTimer::singleShot(int msec, Functor functor)

  多个定时器使用,用完即销毁。

代码语言:javascript复制
QTimer::singleShot(1000, [](){qDebug()<<"Hello world";})
QTimer::singleShot(1000, [](){qDebug()<<"Hello world";})
QTimer::singleShot(1000, [](){qDebug()<<"Hello world";})

  小君在思考,既然C 有lambda这种匿名函数,而Qml使用的是逻辑是js语法,理论上也能实现类似QTimer定时器的效果。

  说起js匿名函数,突然想到Qml的控件截图操作grabToImage使用了js匿名函数。

代码语言:javascript复制
Rectangle {
    id: source
    width: 100
    height: 100
    color: "blue"
    Component.onCompleted: {
        source.grabToImage(function(result) {
            result.saveToFile("1.png");
        });
    }
}

  上面代码中,grabToImage函数接受一个匿名函数的参数。

  既然js也一样支持匿名函数,那么我们就可以动态创建Timer对象,动态销毁,达到单次定时器的效果。

代码语言:javascript复制
function timerOnce(msec, functor) {
    var timer = Qt.createQmlObject('import QtQuick 2.0; Timer {running: true;}',
                                   parentItem,
                                   "MyTimer");
    var func = function() {
        functor()
        timer.destroy()
    }
    timer.interval = msec
    timer.onTriggered.connect(func)
    return timer
}

  使用:

代码语言:javascript复制
timerOnce(2000, function(){console.log("qthub.com")})

  这样我们就可以很方便地使用Qml单次定时器了,关键是调用timerOnce是无状态的,避免外部修改其值,简单易用。

  同样地,它也支持嵌套,比如:

代码语言:javascript复制
timerOnce(2000, function(){
    console.log("Hello world")
    timerOnce(2000, function(){console.log("qthub.com")})
}

1 人点赞