PyQt5中的事件系统
一、什么是Qt中的事件
-
事件(event)是由窗口系统或者Qt自身产生的事情或动作的通称。当用户按下或者松开键盘或鼠标的按键时,就可以产生一个键盘或者鼠标事件;当某个窗口第一次显示的时候,就会产生一个绘制事件,用来告知窗口需要重新绘制它本身,从而使窗口可见。大多数事件是作为用户动作的响应而产生的,但是也有一些例外,比如像定时器事件,则是由系统独立产生的。
-
在使用Qt进行编程开发时,通常不需要考虑事件,因为在发生某些重要的事情时,Qt窗口部件都会发射信号。但是当我们需要编写自己的自定义窗口部件,或者是当我们希望改变已经存在的Qt窗口部件的行为时,事件就变得非常有用了。
-
不应该混淆“事件”和“信号”这两个概念。一般情况下,在使用窗口部件的时候,信号是十分有用的。而在实现窗口部件时,事件则是十分有用的。例如,当使用QPushButton时,我们对于它的clicked信号往往更为关注,而很少关心促成发射该信号的底层鼠标或键盘事件。但是,如果要实现的是一个类似于QPushButton的类,就需要编写一定的处理鼠标和键盘事件的代码,而且在必要的时候,还需要发射clicked()信号。可以看到,事件和信号是两个不同层面的东西,发出者不同,作用也不同。
- 信号是由对象产生的,而事件则不一定是由对象产生的(比如由鼠标产生的事件),事件通常来自底层的窗口系统,但也可以手动发送自定义的事件,可见信号和事件的来源是不同的
- 事件既可以同步使用,也可以异步使用 (取决于调用 sendEvent()还是 postEvents()),而使用信号和槽总是同步的。事件的另一个好处是可以被过滤
-
在Qt中,任何继承自QObject的子类实例,都可以接收和处理事件。
-
Qt中使用 QEvent 及其子类来描述事件(其继承关系见下图),比如 QMouseEvent 类用于描述与鼠标相关的事件,该类保存了与鼠标相关的大量信息,比如是哪一个键激发了该事件、产生该事件时鼠标的位置等。
二、Qt对事件的描述和分类
-
方式一:根据事件的来源和传递方式,事件可分为以下三大类
-
自发事件:这是由窗口系统生成的,这些事件置于系统队列中,并由事件循环一个接一个地处理。
-
发布的事件(Posted events):该类事件由 Qt 或应用程序生成,这些事件由 Qt 排队,并由事件循环处理。
-
发送的事件(Sent events):该类事件由 Qt 或应用程序生成,这些事件直接发送到目标对象,不经过事件循环处理。
-
-
方式二: 事件被细分为很多种类型(有一百多种),每一种类型使用 QEvent 类中的枚举常量进行表示,比如 QMouseEvent 管理的鼠标事件有鼠标双击、移动、按下等类型,这些类型分别使用 QEvent::Type 枚举类型中的枚举常量 MouseButtonDblClick、MouseMove、 MouseButtonPress 表示。所有的类型分类请查阅帮助文档。 可使用函数Type QEvent::type() const;获取事件的类型