Qt -事件循环 补充

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多线程编程中各自扮演重要的角色。

异步调用

https://blog.csdn.net/caoshangpa/article/details/79420547

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt事件循环是一个非常重要的概念,也是Qt能够实现异步、响应式编程的关键所在。简单来说,事件循环是一个无限循环,用于处理Qt应用程序中的各种事件,包括用户输入、定时器事件、网络事件等等。以下是Qt事件循环的原理: 1. 事件队列:Qt应用程序中的所有事件都被放置在一个事件队列中,事件队列是一个先进先出的队列结构。 2. 事件循环Qt应用程序启动后,会进入一个无限循环,也就是事件循环事件循环会不断地从事件队列中取出事件,并将事件分发给对应的对象进行处理。 3. 事件分发:当事件循环从事件队列中取出一个事件时,会根据事件的类型和目标对象,将事件分发给对应的对象进行处理。如果事件是一个用户输入事件,那么它会被分发给当前获得焦点的控件进行处理;如果事件是一个定时器事件,那么它会被分发给对应的定时器对象进行处理。 4. 事件处理:一旦事件被分发给对应的对象,该对象就会调用自己的事件处理函数来处理事件。例如,一个按钮控件的事件处理函数会检测用户是否点击了该按钮,如果是,则执行与该按钮相关的操作。 5. 事件过滤器:Qt框架允许对象在事件处理之前拦截事件进行处理,这个过程称为事件过滤。事件过滤器可以用来处理一些全局事件,例如窗口关闭事件、应用程序退出事件等等。 总之,Qt事件循环是一个非常灵活、高效的机制,可以保证Qt应用程序能够实现异步、响应式编程。开发者只需要关注对象的事件处理函数,无需关心事件循环的具体实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值