QTimer::singleShot + lambda

来源:互联网 发布:java gui聊天程序 编辑:程序博客网 时间:2024/06/08 10:35

[static] void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
This static function calls a slot after a given time interval.
这个静态函数在一个给定时间间隔之后调用一个槽。
It is very convenient to use this function because you do not need to bother with a timerEvent or create a local QTimer object.
使用这个函数是非常方便的,因为你不需要被timerEvent或创建一个本地QTimer对象所困扰
Example:
#include <QApplication>  #include <QTimer>  int main(int argc, char *argv[])  {      QApplication app(argc, argv);      QTimer::singleShot(600000, &app, SLOT(quit()));      ...      return app.exec();  }
This sample program automatically terminates after 10 minutes (600,000 milliseconds).
这个示例程序会自动在10分钟之后终止(也就是600000毫秒)。
The receiver is the receiving object and the member is the slot. The time interval is msec milliseconds.
receiver是正在接收的对象并且member是一个槽。时间间隔是msec。
以上是对singleShot函数的说明,清晰明了,就是一段时间后,执行槽函数,单次定时。


拓展:想一下,如果在一个函数中使用singleShot,槽函数是函数本身,会是什么效果,这样就会是一直循环下去。


void QNeal::eventOperation() {
...........
QTimer::singleShot(10, this, SLOT(eventOperation()));
}


问题来了,这样不是死循环了吗?答案是肯定的,所以应该做个可控的开关,方便在需要的时候关闭循环。
void QNeal::eventOperation() {
...........
if(f_continue)
QTimer::singleShot(10, this, SLOT(eventOperation()));
}


下面对lambda表达式进行讲解(参考网上资料)
基本lambda语法
基本形式如下:
[capture](parameters)->return-type {body}

[]叫做捕获说明符,表示一个lambda表达式的开始。接下来是参数列表,即这个匿名的lambda函数的参数,->return-type表示返回类型,如果没有返回类型,则可以省略这部分。想知道为什么返回类型可以这么表示,这涉及到c++11的另一特性,参见自动类型推导,最后就是函数体部分了。
我们可以这样输出"hello,world"
auto func = [] () { cout << "hello,world"; };
func(); // now call the function

lambda函数能够捕获lambda函数外的具有自动存储时期的变量。函数体与这些变量的集合合起来叫闭包。
[] 不截取任何变量
[&] 截取外部作用域中所有变量,并作为引用在函数体中使用
[=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
[=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[x, &y] x按值传递,y按引用传递
[this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
看到这,不禁要问,这魔法般的变量捕获是怎么实现的呢?原来,lambda是通过创建个小类来实现的。这个类重载了操作符(),一个lambda函数是该类的一个实例。当该类被构造时,周围的变量就传递给构造函数并以成员变量保存起来。看起来跟函数对象很相似。


lambda函数的类型是什么呢,答案是std:function。


最后结合使用


QMessageBox msgBox(this);
msgBox.setText(QString::fromLocal8Bit("连接无法建立,稍后将重试"));
QTimer::singleShot(30000, &msgBox, &QDialog::accept);
msgBox.exec();

提示框30后自动退出,如果提前点击退出了。没有什么影响,信号还是会发出的


lambda表达式,常涉及局部变量、全局变量(类变量)的使用,搞定出闭包的使用很重要。


QString txt = QString::fromLocal8Bit("连接无法建立,稍后将重试");
QTimer::singleShot(3000, this, [txt]
{
QMessageBox msgBox;
msgBox.setText(txt);
QTimer::singleShot(1000, &msgBox, &QDialog::accept);
msgBox.exec();

});

个人理解,如有不对的地方,欢迎指正。QQ:2967732156