一、 概述
PyQt的图形界面应用中,事件处理类似于Windows系统的消息处理。一个带图形界面的应用程序启动后,事件处理就是应用的主循环,事件处理负责接收事件、分发事件、接收应用处理事件的返回结果,在程序中捕获应用关注的事件触发相关事件处理是良好UI开发的必经之路。那么在PyQt的图形界面应用中,有哪些方法可以捕获事件以进行处理呢?下面我们就来分析一下。
二、 应用层级的事件捕获
2.1、notify方法捕获应用事件
PyQt的事件处理是从应用主程序开始的,在PyQt应用主程序中,真正负责事件分发处理的是QApplication类的notify方法(或称为notify函数),该方法负责向接收者发送事件,返回接收事件对象的处理程序返回的值。因此要在应用中捕获事件并进行处理,只要通过从QApplication类派生自定义的应用类并重写notify方法就可以捕获应用接收到的所有事件。
2.1.1、notify的语法
notify(QObject receiver, QEvent event)
其中:
1、参数receiver表示将事件发送给谁;
2、event就是事件参数,类型为QEvent ,如果不了解请参考《PyQt学习随笔:Qt事件类QEvent详解》;
3、返回值为receiver的事件处理方法的返回值,如果返回值是False表示接收者对事件不感兴趣,需要应用将事件信息继续向下传到接收者的父级,依此类推,直至顶级对象,如果返回True表示消费了事件,事件不会再往下传递。
2.1.2、一段notify重写的示例代码
class App(QApplication):
def notify(self, eventobject: QObject, event: QEvent):
"""
本次重写notify是为了截获应用的所有事件,并针对鼠标和键盘按下事件输出事件相关的信息
:param eventobject: 事件接收对象
:param event: 具体事件
:return: True表示事件已经处理,False表示没有处理,需要继续往下传递
"""
eventtype = event.type()
flag = False
if eventtype==QEvent.Close or eventtype==QEvent.KeyPress or eventtype == QEvent.MouseButtonPress: #
flag=True
#if (isinstance(eventobject, QtGui.QWindow)):
#super().notify(eventobject, event)
# return False
if flag:
print(f"In app notify:事件类型值={eventtype},事件接收者:{eventobject},parent={eventobject.parent()},child={eventobject.children()}")
ret = super().notify(eventobject, event)
if flag:
print(f"App notify end,事件接收者:{eventobject},事件返回值={ret},app={self},parent={eventobject.parent()}")
return ret
2.1.3、重写notify方法后的应用主程序示例代码
由于重写notify方法需要使用从QApplication派生自定义类,因此应用主程序的应用对象应该从新派生类构建,实例代码如下:
if __name__ == '__main__':
app = App(sys.argv)
w = eventCap() #界面对象对应类
w.show()
sys.exit(app.exec_())
2.2、安装应用级的事件过滤方法
2.2.1、概述
要捕获应用级的事件,除了Notify方法外,还可以采用安装应用级的事件过滤方法。
事件过滤会接收到所有发给该对象的所有事件,事件过滤可以终止事件或继续将事件提交到这个对象往下处理。事件过滤通过对象的eventFilter() 方法来接收事件,如果事件需要被终止,