Qt的事件循环

Qt事件循环及QEventLo用_qt qeventloop-CSDN博客

实现原理,把不同平台的事件循环进行封装,提供统一的抽象接口。

Application类中,关键就是维护了一个QEventLoop.

Application的exec就是QEventLoop的exec,称为主事件循环"Main EventLoop"。

所有的事件分发,事件处理都从这里开始。

Application还提供了sendEvent和postEvent函数,用来发送事件。

sendEvent发出的事件会被立即处理(同步执行)。

postEvent发送的事件会被加入事件队列,在下一轮事件循环时进行处理(异步执行)。

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

1 main()  
2 QApplication::exec()  
3 [...]  
4 QWidget::event(QEvent *)  
5 Button::mousePressEvent(QMouseEvent *)  
6 Button::clicked()  
7 [...]  
8 Worker::doWork()  

在main()中,调用QApplication::exec()开启事件循环。 

视窗管理者发送了鼠标点击事件,事件被Qt内核捕获,转换为QMouseEvent,随后通过QApplication::notify()发送到widget的event()中。因为Button没有重载event(),它的基类QWidget的event()方法得以调用。QWidget::event()检测出传入的事件的鼠标点击,并调用其专有的事件处理器,Button::mousePressEvent()。我们重载了mousePressEvent()方法,在内部发送clicked()信号,该信号激活了worker对象中的槽函数doWork()。

UI页面,要持续不断地刷新,以保证显示流畅,能及时响应用户输入。一般要有一个良好的帧率,比如每秒刷新60帧,FPS 60,即16ms刷新一次。而当进行一些复杂的计算时,这些计算的耗时远远超过了16ms。在没有计算完成之前,函数不会退出(相当于阻塞),事件循环

得不到及时处理,就会出现UI卡住的现象,此时可以调用QCoreApplication::processEvents(),立即处理一次事件循环,来保证UI的流畅。

QEventLoop类:

The QEventLoop class provides a means of entering and leaving an event loop.

At any time, you can create a QEventLoop object and call exec() on it to start a local event loop. From within the event loop, calling exit() will force exec() to return.

QEventLoop类提供了一种进入和离开事件循环的方法。

在任何时候,您都可以创建QEventLoop对象并在其上调用exec()来启动本地事件循环。在事件循环中,调用exit()将强制exec()返回。

 enum QEventLoop::ProcessEventsFlag

flags QEventLoop::ProcessEventsFlags

This enum controls the types of events processed by the processEvents() functions.

Constant

Value

Description

QEventLoop::AllEvents

0x00

All events. Note that DeferredDelete events are processed specially. See QObject::deleteLater() for more details.

Deferred:延迟的

QEventLoop::ExcludeUserInputEvents

exclude:不包括

0x01

Do not process user input events, such as ButtonPress and KeyPress. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag.

discard:扔掉,弃置

QEventLoop::ExcludeSocketNotifiers

套接字通信

0x02

Do not process socket notifier events. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeSocketNotifiers flag.

QEventLoop::WaitForMoreEvents

0x04

Wait for events if no pending events are available.

pending:待处理的

The ProcessEventsFlags type is a typedef for QFlags<ProcessEventsFlag>. It stores an OR combination of ProcessEventsFlag values.

 [slot] void QObject::deleteLater()

later:随后

Schedules this object for deletion.

Schedule:安排,预定

The object will be deleted when control returns to the event loop.

If the event loop is not running when this function is called

(e.g. deleteLater() is called on an object before QCoreApplication::exec()),

the object will be deleted once the event loop is started.

once:conj:一......就

If deleteLater() is called after the main event loop has stopped, the object will not be deleted.

Since Qt 4.8, if deleteLater() is called on an object that lives in a thread with no running event loop, the object will be destroyed when the thread finishes.

Note that entering and leaving a new event loop (e.g., by opening a modal dialog) will not perform the deferred deletion;

perform:执行

for the object to be deleted, the control must return to the event loop from which deleteLater() was called.

from which:从哪个

Note: It is safe to call this function more than once; when the first deferred deletion event is delivered, any pending events for the object are removed from the event queue.

more than once:不止一次

pending:即将发生的

int QEventLoop::exec(ProcessEventsFlags flags = AllEvents)

Enters the main event loop and waits until exit() is called. Returns the value that was passed to exit().

specified:详细说明的:

If flags are specified, only events of the types allowed by the flags will be processed.

It is necessary to call this function to start event handling. The main event loop receives events from the window system and dispatches these to the application widgets.

dispatches:派遣,发送

Generally speaking:一般来说

interaction:互动

take place:发生

Generally speaking, no user interaction can take place before calling exec().

As a special case, modal widgets like QMessageBox can be used before calling exec(), because modal widgets use their own local event loop.

idle:无事可做;空闲的

To make your application perform idle processing

(i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout. More sophisticated idle processing schemes can be achieved using processEvents().

sophisticated:见多识广的,复杂巧妙的

schemes:方案

 bool QEventLoop::processEvents(ProcessEventsFlags flags = AllEvents)

Processes pending events that match flags until there are no more events to process. Returns true if pending events were handled; otherwise returns false.

especially:尤其

operation:操作

This function is especially useful if you have a long running operation and want to show its progress without allowing user input; i.e. by using the ExcludeUserInputEvents flag.

This function is simply a wrapper for QAbstractEventDispatcher::processEvents(). See the documentation for that function for details.

simply:仅仅

wrapper:包装材料

[pure virtual] bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)

Processes pending events that match flags until there are no more events to process. Returns true if an event was processed; otherwise returns false.

This function is especially useful if you have a long running operation, and want to show its progress without allowing user input by using the QEventLoop::ExcludeUserInputEvents flag.

as follows:如下所示

newly:最近;

If the QEventLoop::WaitForMoreEvents flag is set in flags, the behavior of this function is as follows:

  • If events are available, this function returns after processing them.
  • If no events are available, this function will wait until more are available and return after processing newly available events.

If the QEventLoop::WaitForMoreEvents flag is not set in flags, and no events are available, this function will return immediately.

continuously:连续不断的

Note: This function does not process events continuously; it returns after all available events are processed.

See also hasPendingEvents().

void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)

whichever:无论哪个,取其

Process pending events that match flags for a maximum of maxTime milliseconds, or until there are no more events to process, whichever is shorter. This function is especially useful if you have a long running operation and want to show its progress without allowing user input, i.e. by using the ExcludeUserInputEvents flag.

Specifying:指定

Notes:

  • This function does not process events continuously; it returns after all available events are processed.
  • Specifying the WaitForMoreEvents flag makes no sense and will be ignored.
Qt事件循环是一个非常重要的机制,它负责接收和分发事件,保证 Qt 应用程序的正常运行。下面是简单的 Qt 事件循环源码分析: 1. Qt事件循环是通过 `QCoreApplication::exec()` 方法启动的。该方法首先会创建一个 `QEventLoop` 对象,然后进入一个无限循环。 2. 在事件循环中,`QEventLoop` 对象通过调用 `QCoreApplication::processEvents()` 方法来处理当前队列中的事件。该方法会检查是否有待处理的事件,如果没有,则线程会进入休眠状态,等待新的事件到来。 3. 当一个事件到来时,Qt 会根据事件的类型和目标对象,将事件分发给正确的接收者进行处理。接收者可以是窗口部件、控件、布局等。 4. 对于每个事件,Qt 会调用接收者的对应方法来处理。例如,对于鼠标点击事件,Qt 会调用接收者的 `mousePressEvent()` 方法来处理。 5. 在事件处理过程中,如果需要进行其他操作(如更新界面、执行定时器等),Qt 会将这些操作添加到事件队列中。 6. 当所有待处理的事件都被处理完毕后,Qt 会通过调用 `QCoreApplication::quit()` 方法退出事件循环,程序结束运行。 需要注意的是,Qt事件循环并不是单线程的。在多线程环境下,每个线程都可以有自己的事件循环,但每个线程只能有一个事件循环。当一个事件需要跨线程传递时,Qt 会通过事件队列和线程间的信号槽机制来实现。 以上是简单的 Qt 事件循环源码分析,如果您对具体的源码细节有更深入的需求,建议参考 Qt 的官方文档和源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpl还在学习的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值