Qt ------ 主事件循环与 QEventLoop

Posted 流水灯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt ------ 主事件循环与 QEventLoop相关的知识,希望对你有一定的参考价值。

1、事件循环一般用exec()函数开启。QApplicaion::exec()、QMessageBox::exec()都是事件循环。其中前者又被称为主事件循环。

事件循环首先是一个无限“循环”,程序在exec()里面无限循环,能让跟在exec()后面的代码得不到运行机会,直至程序从exec()跳出。从exec()跳出时,事件循环即被终止。QEventLoop::quit()能够终止事件循环。

其次,之所以被称为“事件”循环,是因为它能接收事件,并处理之。当事件太多而不能马上处理完的时候,待处理事件被放在一个“队列”里,称为“事件循环队列”。当事件循环处理完一个事件后,就从“事件循环队列”中取出下一个事件处理之。当事件循环队列为空的时候,它和一个啥事也不做的永真循环有点类似,但是和永真循环不同的是,事件循环不会大量占用CPU资源。

事件循环的本质就是以队列的方式再次分配线程时间片。

2、事件循环是可以嵌套的,一层套一层,子层的事件循环执行exec()的时候,父层事件循环就处于中断状态;当子层事件循环跳出exec()后,父层事件循环才能继续循环下去。

另外,子层事件循环具有父层事件循环的几乎所有功能。Qt会把事件送到当前生效的那个事件循环队列中去,其中包括Gui的各种事件。所以用户在主线程中执行各种exec()(如QMessageBox::exec(),QEventLoop::exec())的时候,虽然这些exec()打断了main()中的QApplication::exec(),但是Gui界面仍然能够正常响应。    

3、如果某个子事件循环仍然有效,但其父循环被强制跳出,此时父循环不会立即执行跳出,而是等待子事件循环跳出后,父循环才会跳出。
4、当GUI主线程中的某个函数,比如NETWORK的某个函数为非阻塞,比如下面的例子:

  1. 1:  QNetworkAccessManager qnam;    
  2. 2:  QNetworkReply *reply = qnam.get(QNetworkRequest(QUrl(...)));    
  3. 3:  QEventLoop loop;    
  4. 4:  QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));    
  5. 5:  loop.exec();     


get函数为非阻塞,立即返回,但是我想等在这里直至收到真正的数据,这里用一个局部的循环,等待事件完成后关闭局部循环。

以上是关于Qt ------ 主事件循环与 QEventLoop的主要内容,如果未能解决你的问题,请参考以下文章

Qt学习笔记8.Qt中的多线程

如何在 Qt 的主事件循环中使用 std::thread?

Qt/C++ 事件循环异常处理

QT中想在子线程中创建对话窗口怎么建

进入Qt事件循环后如何自动执行方法?

Qt 的线程与事件循环