事件&事件循环

Qt将系统产生的信号(软件中断)转换成Qt事件,事件类都是由QEvent派生的,事件的产生、分发和处理伴随着整个程序的运行周期。Qt是事件驱动的。

Qt的主事件循环

Qt作为一个跨平台的UI框架,其事件循环实现原理, 就是把不同平台的事件循环进行了封装,并提供统一的抽象接口。一般对于带UI窗口的程序来说,“事件”是由操作系统或程序框架在不同的时刻发出的。 当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,计时器触发的时候,都会发出一个相应的事件。

Blog Image
点击查看Qt的事件循环机制

常用操作: 重写event函数(事件)

当ui框架搭建完成以后,往往需要针对用户不同的操作(比如鼠标左击和键盘按下事件等)进行自定义处理,这里就需要重新处理事件的响应,最简单的方法就是重写事件处理函数,如下图所示。

Blog Image

上图是在头文件中定义事件处理函数,本质上就是虚函数的重写,下图表示某一事件的具体实现。

Blog Image

上图表示了一般的键盘事件处理流程,其他事件也类似,比如鼠标事件和定时器事件等。

点击查看event函数详细信息

常用操作: 重写eventFilter函数

上述的重写相关event函数是指当某一事件已经在对象上触发了,我们进行了特别的处理,但在某些情况下,我们需要在事件触发之前对事件进行拦截,在事件的源头上进行操作,这是我们可以重写eventFilter函数,如下如所示。

Blog Image

上图是在头文件中定义事件处理函数,下图表示eventFilter函数的具体实现。注意,如果要是有eventFilter函数,需要先使用installEventFilter()函数在对象上安装事件过滤器;

node->getBaseNodeItem()->installEventFilter(this);表示我们要针对场景中Node节点的事件进行过滤,处理我们自己的响应,如下图所示。

Blog Image

void QObject::installEventFilter ( QObject * filterObj ) 这个函数是 QObject 的一个函数,因此可以安装到任何 QObject 的子类,并不仅仅是 UI 组件。这个函数接收一个 QObject 对象,调用了这个函数安装事件过滤器的组件会调用 filterObj 定义的eventFilter()函数。 例如,textField.installEventFilter(obj),则如果有事件发送到textField 组件是,会先调用 obj->eventFilter()函数,然后才会调用 textField.event()。 当然,你也可以把事件过滤器安装到 QApplication 上面,这样就可以过滤所有的事件,已获得更大的控制权。不过,这样做的后果就是会降低事件分发的效率。 如果一个组件安装了多个过滤器,则最后一个安装的会最先调用,类似于堆栈的行为。

点击查看eventFilter()函数详细信息

常用操作: 自定义事件

Qt 允许创建自己的事件类型,这在多线程的程序中尤其有用,当然,也可以用在单线程的程序中,作为一种对象间通讯的机制。事件的分发既可以是同步的,又可以是异步的,它可以使用过滤器。

点击查看自定义事件详细信息