第5章 事件处理
基于窗体(Widget)的应用程序都是由事件(event)驱动的,鼠标单击、按下某个按键、重绘某个组件、最小化窗口都会产生相应的事件,应用程序对这些事件作出相应的响应处理以实现程序的功能。本章介绍PyQt5中事件的处理方法,包括:
- 常见的特定事件的处理函数及其使用方法。
- 使用event()函数拦截QWidget窗体的事件,然后进行识别和分发处理的方法。
- 使用事件过滤器进行事件拦截和处理的方法。
- 拖放操作的实现方法。
5.1 缺省事件处理
在PyQt5中,事件是一种对象,由抽象类QEvent表示。QEvent还有很多子类表示具体的事件,如QKeyEvent表示按键事件,QMouseEvent表示鼠标事件,QPaintEvent表示窗体绘制事件。
当一个事件发生时,PyQt5会根据事件的具体类型用QEvent相应的子类创建一个事件实例对象,然后传递给产生事件的对象的event()函数进行处理。QObject类及其子类都可以进行事件的处理,但主要还是窗体类(QWidget及其子类)中用到事件处理。
表5-1 常用的事件缺省处理函数
缺省函数名称 | 触发时机 | 参数event类型 |
mousePressEvent() | 鼠标按键按下时触发 | QMouseEvent |
mouseReleaseEvent() | 鼠标按键释放时触发 | QMouseEvent |
mouseMoveEvent() | 鼠标移动时触发 | QMouseEvent |
mouseDoubleClickEvent() | 鼠标双击时触发 | QMouseEvent |
keyPressEvent() | 键盘按键按下时触发 | QKeyEvent |
keyReleaseEvent() | 键盘按键释放时触发 | QKeyEvent |
paintEvent() | 在界面需要重新绘制时触发 | QPaintEvent |
closeEvent() | 一个窗体关闭时触发,例如窗口关闭时 | QCloseEvent |
showEvent() | 一个窗体显示时触发,例如一个窗口显示时 | QShowEvent |
hideEvent() | 一个窗体隐藏时触发,例如一个窗口最小化时 | QHideEvent |
resizeEvent() | 组件改变大小时触发,例如一个窗口改变大小时 | QResizeEvent |
focusInEvent() | 当一个组件获得键盘焦点时触发,如一个QLineEdit组件获得输入焦点 | QFocusEvent |
focusOutEvent() | 当一个组件失去键盘焦点时触发,如一个QLineEdit组件失去输入焦点 | QFocusEvent |
enterEvent() | 当鼠标进入组件的屏幕空间时触发,例如鼠标移动到一个QPushButton组件上 | QEvent |
leaveEvent() | 当鼠标离开组件的屏幕空间时触发,例如鼠标离开一个QPushButton组件 | QEvent |
dragEnterEvent() | 拖动操作正在进行,鼠标移动到组件上方时触发 | QDragEnterEvent |
dragLeaveEvent() | 拖动操作正在进行,鼠标移出组件上方时触发 | QDragLeaveEvent |
dragMoveEvent() | 拖动操作正在进行,鼠标移动时触发 | QDragMoveEvent |
dropEvent() | 当拖动操作在某个组件上放下时触发 | QDropEvent |
图5-1 实例Demo5_1运行时界面
事件与信号是有区别的,但是也有关联。Qt为某个界面组件定义的信号通常是对某个事件的封装,例如QPushButton有clicked()信号和clicked(bool)信号,就可以看做是对mouseReleaseEvent()事件的不同封装。
但是某些时候,一个界面组件无法提供需要的信号,例如QLabel没有doubleClicked()信号,就无法通过信号与槽的方式实现QLabel组件的鼠标双击响应。但是,可以通过事件处理和自定义信号创建一个具有doubleClicked()信号的新的标签类。
5.2 事件拦截与事件过滤
一个界面组件产生的事件首先会发送给其event()函数做处理,如果event()函数不做任何处理,就自动调用事件对应的缺省处理函数。根据这个特性,可以在event()函数里做一些事件屏蔽或预处理工作。
PyQt5的事件处理还提供了一个强大的功能:事件过滤器(event filter),可以将一个对象的事件委托给另一个对象来监测并处理。
图5-5 实例Demo5_4运行时界面
5.3 拖放事件与拖放操作
拖放过程由两个操作组成:拖动(drag)和放置(drop)。被拖动的组件称为拖动点(drag site),接收拖动操作的组件称为放置点(drop site)。拖动点与放置点可以是不同的组件,甚至是不同的应用程序,也可以是同一个组件。
本节通过实例Demo5_5演示一个drop site功能的实现,这是一个比较实用的实例。实例运行时界面如图5-6所示,从Windows资源管理器中拖动一个JPG图片文件到实例程序窗口上,实例程序会显示拖动事件的mimeData数据,并显示图片。实例程序窗口只接受JPG文件,其他文件一律不接受。
图5-6 从Windows的资源管理器里拖一个jpg图片文件到示例Demo5_5的窗口
5.4 具有拖放操作功能的组件
本节的实例程序Demo5_6演示了QListWidget、QTableWidget、QTreeWidget的拖放操作功能,程序运行时界面如图5-7所示,有四个具有拖放操作功能的界面组件。在窗体上方还可以对这4个界面组件进行拖放操作相关的设置。在“设置对象”分组框里选择一个对象后,在“拖放参数设置”框里会显示这个组件的4个属性的值,也可以设置对象的这4个拖放操作属性。拖放操作的4个属性的设置影响到组件的拖放操作的特性
图5-7 示例Demo5_6,具有拖放操作的界面组件