1. 事件处理机制
1.1 GUI应用程序的事件处理
- QT事件产生后,会被立即发送给对应的QWidget对象
- 对应的QWidget中的event(QEvent*) 进行事件处理
- event(QEvent*) 根据事件类型调用不同的事件处理函数
- 在时间处理函数中发送QT预定义的信号
- 调用信号关联的槽函数
1.2 信号与时间的区别
- 事件由具体的QWidget(子)对象进行处理,信号由具体的QWidget(子)对象生成
- 改写事件处理函数可能会导致程序行为发生改变,信号是否存在对应的槽函数不会改变程序的行为
- 通常,信号在具体的事件处理函数中产生
1.3 调度方式
Qt的事件循环是异步的,一旦调用QApplication::exec( ),就会进入事件循环。先处理Qt事件队列中的事件,直至为空;再处理系统消息队列中的消息,直至为空;对系统消息进行处理时,会有新Qt事件的产生,需要对其再次进行处理
1.4 事件的处理和过滤
- 重写特定事件处理函数,最常见的事件处理办法
- 重写event( ) 函数,需调用父类 event( ) 函数处理不需要处理或不知如何清理的事件
- 在Qt对象上安装事件过滤器
以A监视过滤B为例- 调用B的installEventFilter( const Qobject *obj ) ,以A的指针为参数,所有发给B的事件都先由A的eventFilter( ) 处理
- A重写Qobject::eventFilter( ) 函数,在eventFilter( ) 中对事件进行处理
- 给QApplication对象安装事件过滤器
安装过滤器后,任意事件在发往其他过滤器时,必须先经过eventFilter( ) - 继承QApplication类,并重载notify( ) 函数
在事件过滤器获取事件之前,先获取到事件
1.5 自定义事件与事件处理
- 手动发送事件
- 构造事件对象
QEvent *event = new QEvent(QEvent::Close) - 发送事件给指定对象
QApplication::sendEvent(this, event)
- 构造事件对象
- 定制某组件的事件处理:确定需要处理的组件–> 重写对象的event( ) 函数
- 事件过滤
- 确定过滤的事件 --> 构造事件过滤类 --> 实例化过滤对象 --> 调用函数在目标对象中安装过滤器
- 事件发送
- 阻塞型事件发送——事件发送后需等待事件处理完成
- 非阻塞型时间发送——事件发送后立即完成,被发送到事件队列中等待处理
2. 信号与槽机制
2.1 定义
信号Signal——由操作系统产生的消息
槽Slot——程序中的消息处理函数
- Public slots——任意对象都可将信号与该槽相接
- Protected slots——仅当前类及其子类可将信号与该槽相接
- Private slots——只有当前类自己可将信号与槽相接
- 自定义槽,只有QObject的子类可以自定义
二者通过 connect 进行绑定,且连接必须发生在两个QT对象之间
2.2 局限
- 在实时系统中,传输速度不如回调函数
- 定义槽函数时,需避免再发送所接受到的同样信号
- 当单个信号和多个槽关联,且被发射时,槽函数的调用顺序是随机无序的
- 宏定义不可用于信号或槽的参数
- 信号和槽的参数不可缺省,且不可用模板类参数
- 嵌套的类不可位于信号或槽区域中,且不能有信号或槽
- 信号或槽声明区中,不能出现友元声明