PyQt程序通过调用QApplication类的exec_()(sys.exit(app.exec_()) 进入程序主循环,开始处理事件,它从事件队列中获取本地窗口系统事件,将它们转化为 QEvents,然后将转换后的事件发送给 QObjects对象。

在QApplication类中,真正负责事件分发处理的是QApplication类的notify方法(函数),该方法负责向接收者发送事件,返回接收事件对象的处理程序返回的值。请注意,对于发送到任何线程中的任何对象的所有事件,都会调用此方法。

对于某些类型的事件(例如鼠标和键事件),如果接收者对事件不感兴趣(例如,它返回false),则事件将传播到接收者的父级,依此类推,直至顶级对象。

因此从QApplication类派生自定义类并重写notify方法可以截获应用接收到的所有事件。

重写notify的语法:

notify(QObject receiver, QEvent event)

其中:

1、参数receiver表示将事件发送给谁;

2、event就是事件参数,如果不了解请参考《PyQt学习随笔:Qt事件类QEvent详解》的介绍;

3、返回值为receiver的事件处理方法的返回值,如果返回值是False表示不阻拦事件,将事件信息继续向下传递,如果返回True表示消费了事件。

案例代码:

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.MouseButtonPress or eventtype==QEvent.KeyPress:flag=True
if flag:
print(f"***************in app notify,事件类型值={eventtype},事件接收者:\n{eventobject}")
ret = super().notify(eventobject, event)
if flag:print(f"***************in app notify,事件返回值={ret}")
return ret

当点击窗口的一个按钮时,上述代码输出信息如下:

***************in app notify,事件类型值=2,事件接收者:
<PyQt5.QtGui.QWindow object at 0x00000000034CE168>
***************in app notify,事件类型值=2,事件接收者:
<PyQt5.QtWidgets.QPushButton object at 0x00000000034CE288>
***************in app notify,事件返回值=True
***************in app notify,事件返回值=True

可以看到,一个按钮鼠标点击事件被传递了两次,首先传递给窗口,然后传递给了按钮。

注意:

1、如果重写此函数,则必须确保处理事件的所有线程在应用程序对象开始销毁之前停止执行此操作。这包括可能正在使用的其他库启动的线程,但不适用于qt自己的线程;

2、这个函数在Qt6规划的版本中将取消。


博客地址:https://blog.csdn.net/LaoYuanPython

老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/98245036

PyQt学习随笔:通过自定义类重写QApplication的notify方法捕获应用的所有消息的更多相关文章

  1. PyQt学习随笔:自定义Qt事件可以使用的事件类型的常量值范围

    除了<PyQt学习随笔:Qt事件QEvent.type类型常量及其含义资料速查>介绍的Qt已经定义的事件外,Qt还支持自定义事件. 为了方便起见,可以使用 registerEventTyp ...

  2. PyQt学习随笔:自定义信号连接时报AttributeError: 'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 如果使用自定义信号,一定要记得信号是类变量,必须在类中定义,不能在实例 ...

  3. PyQt学习遇到的问题:重写notify发送的消息为什么首先给了一个QWindow对象?

    在PyQt开发图形界面应用时,从QApplication派生的子类重写notify方法后(具体请参考<PyQt学习随笔:通过自定义类重写QApplication的notify方法捕获应用的所有消 ...

  4. PyQt学习随笔:Qt事件类QEvent详解

    QEvent类是PyQt5.QtCore中定义的事件处理的基类,事件对象包含了事件对应的参数. <Python & PyQt学习随笔:PyQt主程序的基本框架>介绍了PyQt程序通 ...

  5. PyQt学习随笔:Model/View开发时从Model相关类派生自定义类需要注意的问题

    在<PyQt学习随笔:重写setData方法截获Model/View中视图数据项编辑的注意事项>介绍的方法,从Model相关类派生自定义类,通过重写setData方法以获取View中数据的 ...

  6. PyQt学习随笔:重写setData方法截获Model/View中视图数据项编辑的注意事项

    根据<PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法>可以重写从PyQt的Model类继承的setData方法来实时截获View中对数据的更改,但需要注意 ...

  7. PyQt学习随笔:Qt中Model/View中的怎么构造View匹配的Model

    老猿Python博文目录 老猿Python博客地址 在<PyQt学习随笔:Qt中Model/View相关的主要类及继承关系>介绍了Model/View架构的主要类,在实际使用时,view相 ...

  8. PyQt学习随笔:Model和View之间的数据互动过程

    在<PyQt学习随笔:Qt中tem Views(Model-Based)和Item Widgets(Item-Based)控件的用途和关系>中介绍了,Model用于存储数据,View用于展 ...

  9. PyQt学习随笔:Model/View开发时在view数据项中设置不同角色数据的方法

    在往Model中通过QStandardItem等类插入数据项时,除了实际插入的存储数据,还可以设置不同角色(请参考<PyQt学习随笔:Model/View中诸如DisplayRole的数据角色及 ...

随机推荐

  1. vue实现带logo的二维码/商品条形码/打印商品吊牌

    一.带logo的二维码 1.安装 npm install vue-qr --save 2.在页面或组件中使用 <template> <div id="qrcode" ...

  2. 【译】理解Rust中的闭包

    原文标题:Understanding Closures in Rust 原文链接:https://medium.com/swlh/understanding-closures-in-rust-21f2 ...

  3. ubuntu12.04管理文件系统工具

    ubuntu12.04管理文件系统工具 以前可以自动管理系统盘和移动硬盘,刚重新安装了UBUNTU12.04LTS之后不行了,原来是这个工具: "PCMANFM" 群星_-_偏偏喜 ...

  4. 磁盘构造/msdos分区(fdisk)格式化(mkfs)和挂载

    分区不是必要的,分区是与系统盘分开,防止数据丢失. 磁盘使用流程:查看磁盘(fdisk -l)---分区---格式化(创建文件系统)----挂载(自动挂载) 分区表类型:msdos(一般是系统分区)  ...

  5. 11Linux之软件包管理

    11Linux之软件包管理 目录 11Linux之软件包管理 11 软件包管理 11.1 软件包介绍 11.1.1 编程语言分类 11.1.2 三种安装包 11.2 rpm包管理 11.2.1 rpm ...

  6. 使用 ffmpeg 命令直播推流

    CMD使用到的命令 D: -> 表示进入D盘cd /live -> 表示进入某个路径 执行条件 1.ffmpeg.exe 与视频放在同一目录下,纯英文目录2.执行以上命令进入到ffmpeg ...

  7. linux系统中 SElinux安全子系统

    1.SElinux 是什么? SElinux(Security-Enhanced Linux)是美国国家安全局在linux开源社区的帮助下开发的一个强制访问控制(Mandatory Access Co ...

  8. vue项目中h5移动端中通过flex布局实现首尾固定,中间滚动(借鉴)

    html中 <div class="flexLayoutr"> <div class="div_head"></div> & ...

  9. python应用(2):写个python程序给自己用

    用python写一个程序,然后在命令行上执行,看不到界面(UI),这种程序很常见了,叫命令行程序.然而很多人,特别是不懂程序的人,更需要看到的是一个有界面的,能通过鼠标操作的程序,毕竟已经迈进&quo ...

  10. Pypi项目包发布

    前言 用过python的人肯定对pip安装不陌生,pip安装的包的来源都是在Pypi上.为了能随时能使用自己的包,所以尝试一下将自己的包发布到Pypi上. 步骤 一.准备项目 一.创建目录结构 二.准 ...