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.