仔细来看,事件与信号其实并无多大差别,从我们对其需求上来说,都只要能注册事件或信号响应函数,在事件或信号产生时能够被通知到即可。但有一项区别在于,事件处理函数的返回值是有意义的,我们要根据这个返回值来确定是否还要继续事件的处理,比如在QT中,事件处理函数如果返回true,则这个事件处理已完成,QApplication会接着处理下一个事件,而如果返回false,那么事件分派函数会继续向上寻找下一个可以处理该事件的注册方法。信号处理函数的返回值对信号分派器来说是无意义的。
事件(event)是由窗口系统或者Qt自身产生的,用以响应所发生的各类事情。当用户按下或者松开键盘或者鼠标上的按键时,就可以产生一个键
盘或者鼠标事件;当某个窗口第一次显示的时候,就会产生一个绘制事件,用来告诉窗口需要重新绘制它本身,从而使得该窗口可见。大多数事件是
作为用户动作的响应而产生的,但是也有一些例外,比如像定时器事件,则是由系统独立产生的。
一般情况下,在使用窗口部件的时候,Qt的窗口部件往往都会发送信号,而这时信号也是十分有用的,但是当我们需要编写自己的自定义窗口部
件的时候,又或者是我们想改变已经存在的Qt的窗口部件的行为的时候,事件就变的非常有用了。例如,当我们使用QPushButton时,我们对于它的
clicked()信号往往更为关注,而很少关心促成发射该信号的底层鼠标事件或者键盘事件。但是我们要实现的是一个类似于QPushButton,或者说我们
要实现一个QPushButton的话,就要编写一定的处理鼠标和键盘的事件的代码,而且在必要的时候,还需要发射clicked()信号。可以这么想信号是命
令而事件就是消息,一个战场上的军官只要在等到准确的消息之后,才会根据所传来的消息然后下达命令。
信号和事件的区别就在与,事件比信号更加底层,而且如果一个信号对应多个槽的话,信号的传递是无序的,而事件的传递是有序的。其实在多
线程的实现也依赖与Qt的事件处理机制。以上我们对于事件有了初步的了解了。下面我们继续对事件进行更细致的了解。
在QT中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent.接下来依次谈谈QT中有谁来产生,分发,接受和处理事件:
1.谁来产生事件:最容易想到的是我们的输入设备,比如键盘,鼠标产生的事件keyPressEvent,keyReleaseEvent,mousePressEvent事件(他
们被封装成QMouseEvent和QKeyEvent),这些事件来自于底层的操作系统,他们可以异步的形式通知Qt事件处理系统,后文会仔细道来。当然QT自己
也会产生很多事件,比如QObject::startTimer()会触发QTimerEvent。用户的程序还可以自己定制事件。
2.谁来接受和处理事件:答案是QObject。在Qt的内省机制剖析一文中已经介绍QObject类是整个QT对象模型的心脏,事件处理机制是QObject
三大职责(内存管理,内省(intropection)与事件处理)之一。任何一个想要接受并处理事件的对象均须继承自QObject,可以选择重QObject::event
()函数或事件的处理权交给父类。
3.谁来负责分发事件:对于non-GUI的QT程序,是由QCoreApplication负责将QEvent分发给QObject的子类-Receiver.对于Qt GUI程序,由
QApplication来负责。
在QT中,事件就是QEvent子类的一个实例。Qt处理的事件类型有一百多种
QEvent::None 0 Not an event.
QEvent::AccessibilityDescription 130 Used to query accessibility description texts (QAccessibleEvent).
QEvent::AccessibilityHelp 119 Used to query accessibility help texts (QAccessibleEvent).
QEvent::AccessibilityPrepare 86 Accessibility information is requested.
QEvent::ActionAdded 114 A new action has been added (QActionEvent).
QEvent::ActionChanged 113 An action has been changed (QActionEvent).
QEvent::ActionRemoved 115 An action has been removed (QActionEvent).
QEvent::ActivationChange 99 A widget's top-level window activation state has changed.
QEvent::ApplicationActivate 121 The application has been made available to the user.
QEvent::ApplicationActivated ApplicationActivate This enum has been deprecated. Use
ApplicationActivate instead.
QEvent::ApplicationDeactivate 122 The application has been suspended, and is unavailable to the user.
QEvent::ApplicationFontChange 36 The default applica