Qt事件处理机制

1.Qt事件简述

Qt的事件主要分为两种:

  • 操作系统产生
  • Qt应用程序产生

首先,所有的Qt事件均继承抽象类QEvent,其描述程序内部或外部发生的动作。任意的QObject对象都具备处理Qt事件的能力。

在发生事件时,会产生一个QEvent对象,这个对象会传递给当前组件的event( )函数。如果当前组件没有安装事件过滤器,则会将QEvent对象发放到相应的xxxEvent( )函数中。

不同的QEvent对象会有各种各样的属性,比如:鼠标按下的属性
在这里插入图片描述

So,总体的流程如下:
Qt的main() 函数中创建一个App对象,然后调用exec( )函数,此时App会进入消息循环,可以监听App的事件,如果发生事件就会生成一个QEvent对象。
(1) 由操作系统产生的事件:
操作系统获取到一个鼠标按压的事件,会将该事件放入到系统的消息队列中,Qt消息循环的时候读取消息队列中的消息,转化为QEvent对象并被分发到相应的QWidget对象,event(QEvent *)函数会对事件进行处理(根据事件类型调用不同的事件处理函数),在事件处理函数中发送Qt预定义的信号,最终调用信号关联的槽函数

(2) Qt 应用程序自己产生
程序产生事件有两种方式:
一种是调用Application::postEvent( )函数:例如QWidget::update( )函数,它new一个paintEvent( ),然后调用Application::postEvent( )将其放入Qt的消息队列中,等待依次被处理;

另一种是调用sendEvent( )函数:事件不会放入消息队列,而是直接被派发和处理。Qwidget::repaint( )函数就是会被立即处理,也就是阻塞型的。

2.Qt事件的处理

(1)调度方式
事件有两种调度方式:同步和异步

Qt的事件循环是异步的,当调用exec()时,就进入了消息循环。先处理Qt事件队列中的事件,直到为空,再处理系统消息队列中的消息,直至为空。吹系统消息队列的时候会产生新的Qt事件,需要对其再次进行处理。

调用sendEvent的时候,消息会立即被处理,是同步的(阻塞的)。实际上sendEvent( )是通过调用QApplication::notify( ), 直接进入了事件的派发和处理。

(2)事件的派发和处理
事件过滤器是Qt中一个独特的事件处理机制。通过事件过滤器,可以让一个对象侦听拦截另一个对象的事件。

事件过滤器实现如下:
在基类QObject中有一个类行为QObjetList的成员变量,名为eventFilters,当某个QObject(A)给另一个QObject(B)安装了事件过滤器后,B会把A的指针保存在eventFilters中,在B处理事件前,会先去检查eventFilters列表,如果非空,就先调用列表中对象的eventFilter( )函数。一个对象可以给多个对象安装过滤器,一个对象能同时被安装多个过滤器,在事件到达之后,事件过滤器以安装次序的反序被调用。

事件过滤器的返回值如果为true,则表示事件已经被处理完毕,Qt将直接返回,进行下一事件的处理。如果返回false,事件则将接着被送往剩下的事件过滤器或目标对象进行处理。

Qt中事件的派发是从QApplication::notify( )开始的,因为QApplication也是继承自QObject,所以先检查QApplication对象,如果有事件过滤器安装在它身上,先调用事件过滤器,接下来QApplication::notify( )会过滤或合并一些事件(比如失效widget的鼠标事件会被过滤掉,而同一区域重复的绘图事件会被合并),事件被送到reciver::event( )处理。

(3)事件的转发
对于某些类别的事件,如果在整个事件的派发过程结束后还没被处理,那么这个事件将会向上转发给他的父widget,直到顶层窗口。
QT事件处理机制
Qt5事件机制详解

你可能感兴趣的:(Qt,qt)