qt的事件循环,就是把不同平台的事件循环进行了封装,并提供统一的抽象接口
QEventloop事件循环类
int exec(QEventLoop::ProcessEventsFlags,flags=AllEvents)
void exit(int returnCode=0)
bool isRunning() const
bool processEvents(QEventLoop::ProcessEventsFlags,flags=AllEvents)
void processEvents(QEvenyLoop::ProcessEventsFlags,int maxTime)
void wakeUp()
EventLoop是事件循环类
exec() 启动事件循环,调用exec后,调用exec的函数就会被阻塞,直到EventLoop里面的while循环结束
exit()是退出实现循环,即将EventLoop中的退出标识设置为true,(应该是在派发事件后,某个事件处理的函数中,达到事件退出条件时,调用exit函数,将EventLoop中的退出标志设为true)
一般,main函数中都有一个QCoreApplication/QGuiApplication/QApplication,并在末尾调用exec
QApplication类中,除去启动参数、版本等相关东西,还维护了一个QEventLoop,QApplicatinon的exec就是QEventLoop的exec
注意,Application中的这个EventLoop,叫做主事件循环,main EventLoop,所有的事件分发、事件处理都是从这里开始的
int main(int argc, char *argv[])
{
QApplication a(argc, argv); // 或者QGuiApplication 或者QCoreApplication
Widget w;
w.show();
return a.exec();
}
Application还提供了sendEvent和poseEvent两个函数,分别用来发送事件
sendEvent发出的事件会立即被处理,也就是同步执行
postEvent发送的事件会被加入到事件队列中,下一轮事件循环时才处理,也就是异步执行
sendPostedEvents函数,是将已经加入队列中的准备异步执行的事件立即同步执行
processEvents方法不阻塞UI,用于立即执行一次事件循环
(UI界面应该是不断刷新的,也就是触发paintEvent事件,以保证流畅等情况,但是如果一些计算想当耗时的操作,事件循环得不到及时的处理,就会发生UI卡住的现象,这种场景下,就可以使用processEvents,来立即处理一次事件循环,来保证UI的流畅)
somework() // 耗时操作
// 在适当的位置,插入一个processEvents 保证事件循环被处理
QCoreApplication::processEvents()
somework() // 耗时操作
通常异步操作,直接使用信号槽机制就可以
如果要设计成同步调用,就使用本地QEventLoop
事件产生,spontaneous事件和非spontaneous事件,即程序外部产生和程序内部产生
多数情况下来自操作系统并且通过spontaneous函数返回true来获知事件来自程序外部
当spontaneous函数返回false活命事件来自程序内部
线程相关性
当创建一个QObject时,它会与创建自己所在的线程绑定,它他参与的消息循环,其实是它所在线程的消息循环
加入某个线程没有默认的QThread::exec(),那么该线程上的QObject则无法接收事件
另外,如果两个不同线程的QObject需要互相通信,那么只能通过QueuedConnection的方式(通过QueuedConnection连接的信号,其实是将一个事件压入了实现循环中),异步的通知对方线程,在下一轮时消息循环处理QObject的消息
QObejct的线程相关默认会和他的parent保持一致,如果一个QObject没有parent,那么通过moveToThread,将他的线程相关性切换到指定线程
事件循环与多线程
在Qt中,事件循环(Event Loop)是一个重要的概念,用于处理事件和信号的分发。而QThreadData则是用于管理线程相关数据的类。
事件循环是通过QCoreApplication或QApplication来运行的,它负责不断地从系统消息队列中获取事件,并将其传递给相应的接收者进行处理。事件循环会在没有待处理事件时进入休眠状态,直到有新的事件到达或触发了特定的条件(如定时器超时、异步操作完成等)。通过事件循环,Qt能够实现异步操作、定时器、网络通信等功能。
QThreadData是Qt内部用于管理线程相关数据的类,每个线程在Qt中都有一个对应的QThreadData对象。它包含了与线程相关的一些数据结构,例如事件循环(线程的事件循环)、线程存储的局部数据(Thread Local Storage,TLS)等。QThreadData还提供了一些公共接口,允许其他Qt模块和对象在多线程环境中进行线程相关的操作。
在Qt中,每个线程都有一个默认的事件循环(QThreadData::eventLoop)。当线程运行时,该事件循环会被自动创建并启动,用于处理线程中的事件。事件循环会阻塞线程,直到有事件到达或满足退出条件。除了默认事件循环,Qt还支持在不同线程中创建自定义的事件循环。
需要注意的是,QThreadData和事件循环是两个独立的概念。QThreadData主要用于管理线程相关数据,而事件循环用于处理事件和信号的分发。它们在Qt的多线程编程中起到不同的作用,但也有一定的关联关系,因为每个线程都有一个对应的QThreadData对象,并且事件循环是QThreadData的一部分。
总结:事件循环(Event Loop)负责处理事件和信号的分发,使得Qt能够实现异步操作、定时器等功能。QThreadData是用于管理线程相关数据的类,包含了线程的事件循环和其他线程相关的数据结构。它们在Qt多线程编程中各自扮演重要的角色。