本文介绍如何使用Qml定时器与js的匿名函数的结合,解决定时器的繁杂操作。
Qml使用定时器一般是这样的:
Timer {
interval: 1000
running: true
onTriggered: {
/* dosomething */
}
}
但如果有多个定时器任务,则需要创建多个Timer对象,而这些对象没有销毁,导致内存长期占用。特别是那些只执行一次的定时器。
如果Qml使用定时器能像Qt下面代码一样使用定时器多好啊。
QTimer::singleShot(int msec, Functor functor)
多个定时器使用,用完即销毁。
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匿名函数。
Rectangle {
id: source
width: 100
height: 100
color: "blue"
Component.onCompleted: {
source.grabToImage(function(result) {
result.saveToFile("1.png");
});
}
}
上面代码中,grabToImage函数接受一个匿名函数的参数。
既然js也一样支持匿名函数,那么我们就可以动态创建Timer对象,动态销毁,达到单次定时器的效果。
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
}
使用:
timerOnce(2000, function(){console.log("qthub.com")})
这样我们就可以很方便地使用Qml单次定时器了,关键是调用timerOnce是无状态的,避免外部修改其值,简单易用。
同样地,它也支持嵌套,比如:
timerOnce(2000, function(){
console.log("Hello world")
timerOnce(2000, function(){console.log("qthub.com")})
}