1.事件驱动模式
在事件驱动的程序中,GUI视图需要响应object的状态变化,作出特定反应。当状态变化时,将对应的信息发送给接收者。
事件的来源有两类,一种是系统事件,例如鼠标键盘事件,qt获取到这些来自系统底层的消息,将它们转换成qt的事件,放入事件队列;另一种是应用程序事件,例如postEvent/sendEvent。
事件通过各种各样的方式在object间传递。QWidget通过QEvent发送给其他QObject,以相应鼠标或键盘操作;QObject之间可通过signal/slot机制进行事件处理。
2.事件处理流程



3.event loop
下面是一个典型的qt主程序示例:
int main(int argc, char * argv[]) {
QApplication myapp(argc, argv); 
QWidget rootWidget;
setGui(&rootWidget);
rootWidget.show(); 
return myapp.exec(); 
};
 |
Every GUI, multithreaded, or event-driven Qt Application must have a QApplication object defined at the top of main(). |
 |
Show the widget on the screen. |
 |
Enter an event loop. |
当调用QApplication::exec()函数之后,程序就进入了event loop,接收、处理、分发各种事件,直到程序退出。QApplication::exec()的简化逻辑如下所示:
while ( !app_exit_loop ) {
while( !postedEvents ) { processPostedEvents() }
while( !qwsEvnts ){ qwsProcessEvents(); }
while( !postedEvents ) { processPostedEvents() }
}
4.事件处理和事件过滤方法
1)QEvent子类
qt4.*中继承自QEvent的子类有QTimerEvent, QMouseEvent, QWheelEvent, QTabletEvent, QKeyEvent, QFocusEvent, QPaintEvent, QMoveEvent, QResizeEvent, QCloseEvent, QIconDragEvent, QShowEvent, QHideEvent, QContextMenuEvent, QIMEvent, QDropEvent, QDragLeaveEvent, QChildEvent, QCustomEvent.
开发者可以通过重载QWidget和QObject提供的事件处理方法,来响应对应的事件。例如,重载QWidget::mousePressEvent ( QMouseEvent * e )之后,我们就可以自行处理窗体的鼠标点击事件。
2)QObject::event()
通过重载event(),可以在某些事件到达本实例的特定事件处理器之前处理他们。对于那些没有明确需要预先处理的事件,需要调用其基类的event()函数。
3)QObject event filter
QObject::installEventFilter ( const QObject * filterObj )方法将filterObj注册为本对象的事件监视对象,即所有本对象的事件都会发送到filterObj。filterObj在QObject::eventFilter(QObject *o, QEvent *e )方法中截获并过滤所有事件,重载此方法,在其中过滤特定的事件。在对特定事件进行过滤之后,eventFilter需要返回TRUE,若不需要过滤或者要将过滤后的事件继续传递下去,则返回FALSE,此时要保证不要delete掉事件e。
一个监视器可以监视多个QObject,一个QObject可以被多个监视器监视,如果QObject被多个监视器监视,则消息按照监视器被注册的顺序传递到各个监视器。
4)QApplication::notify()
Qt调用QApplication::notify( QObject * receiver, QEvent * e )方法将事件e发送到receiver。
5)注册QApplication的监视器
所有事件在被处理和过滤之前,将被此监视器过滤。