PyQt5事件处理
事件介绍
事件的处理机制非常的复杂,属于PyQt底层的事,不必我们关心,学会使用就行。如果说事件是用来创建窗口,那么信号与槽就是用来对这个控件进行处理。事件属于低级的处理方式,信号与槽是高级的处理方式,一般信号与槽处理不了的问题,再使用事件处理。信号与槽功能强大使用简单但是不能解决所有的问题,事件使用麻烦但是可以处理全部的问题。事件的处理主要是重载类方法,信号与槽的处理主要是绑定、发送以及处理。
事件
重写mousePressEvent,keyPressEvent,paintEvent等方法,最常用(控件级)
重写QObject.event方法,一般在PyQt没有提供该事件的处理方法时使用(控件级)
安装事件过滤器:如果对QObject调用installEventFilter,相当于对这个QObject对象添加了一个过滤器。对于QObject的全部事件来说,都会先经过过滤器的处理,在过滤器里面就可以进行我们自己的处理,比如修改丢弃等,慎用,因为会处理所有的事件,会降低效率(控件级)
在QApplication中安装事件过滤器:比QObject的过滤器更强大,对所有的QObject的所有事件进行过滤,且第一时间捕获。事件的过滤先经过QApplication的处理再进过QObject的处理,必须慎用(应用级)
重写QApplication的notify方法,要想在任何事件被处理之前捕获事件,唯一的方法就是重写QApplication的notify方法,一般只在调试中使用(应用级)
事件处理流程(紫色部分是应用级处理,绿色部分是对象级处理)
例子
import sys from PyQt5.QtCore import QEvent
from PyQt5.QtWidgets import QApplication, QWidget class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__() def mousePressEvent(self, mouseEvent):
print('MyWidget.mousePressEvent')
return QWidget.mousePressEvent(self, mouseEvent) def event(self, event):
if event.type() == QEvent.MouseButtonPress:
print('MyWidget.event')
return QWidget.event(self, event) def eventFilter(self, object, event):
if event.type() == QEvent.MouseButtonPress:
print('MyWidget.eventFilter')
return QWidget.eventFilter(self, object, event) class MyQApplication(QApplication):
def __init__(self, param):
super(MyQApplication, self).__init__(param) def notify(self, object, event):
if event.type() == QEvent.MouseButtonPress:
print('MyQApplication.notify')
return QApplication.notify(self, object, event) def eventFilter(self, object, event):
if event.type() == QEvent.MouseButtonPress:
print('MyQApplication.eventFilter')
return QApplication.eventFilter(self, object, event) if __name__ == '__main__':
app = MyQApplication(sys.argv)
app.installEventFilter(app)
w = MyWidget()
w.installEventFilter(w)
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
信号与槽
信号与槽是PyQt的核心机制,也是对象与对象之间的通信方法。信号与槽函数的对应方式是多对多,且信号可以连接信号。除了控件默认的信号外,可以自己定义和实现信号。
信号定义:
mySignal = pyqtSignal([param])
连接信号到槽:
mySignal.connect(handlerFunc)
发送信号:
mySignal.emit([param])
断开信号与槽:
mySignal.disconnect(handlerFunc)
例子:自定义信号并实现与槽的链接
import sys
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
mySignal = pyqtSignal() def __init__(self):
super(MyWidget, self).__init__()
button = QPushButton(self)
button.setText('点我')
button.clicked.connect(self.buttonClicked)
self.mySignal.connect(self.mySignalHandler) def buttonClicked(self):
print('button clicked emit and handler')
self.mySignal.emit() def mySignalHandler(self):
print('my signal emit and handler') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
信号与槽高级玩法
信号重载
import sys
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
# 无参数信号
mySignal_no_aram = pyqtSignal()
# 带一个整型参数信号
mySignal_int = pyqtSignal(int)
# 带一个整型或字符串信号
mySignal_int_or_str = pyqtSignal([int], [str])
# 带两个参数,int和srt 或 str和str
mySignal_two_param = pyqtSignal([int, str], [str, str]) def mySignal_no_aram_handler(self):
print('mySignal_no_aram_handler') def mySignal_int_handler(self):
print('mySignal_int_handler') def mySignal_int_or_str_int_handler(self):
print('mySignal_int_or_str_int_handler') def mySignal_int_or_str_str_handler(self):
print('mySignal_int_or_str_str_handler') def mySignal_two_param_int_str_handler(self):
print('mySignal_two_param_int_str_handler') def mySignal_two_param_str_str_handler(self):
print('mySignal_two_param_str_str_handler') def __init__(self):
super(MyWidget, self).__init__()
button = QPushButton(self)
button.setText('点我')
button.clicked.connect(self.onClicked) # 绑定信号到槽函数
self.mySignal_no_aram.connect(self.mySignal_no_aram_handler)
self.mySignal_int.connect(self.mySignal_int_handler)
self.mySignal_int_or_str[int].connect(self.mySignal_int_or_str_int_handler)
self.mySignal_int_or_str[str].connect(self.mySignal_int_or_str_str_handler)
self.mySignal_two_param[int, str].connect(self.mySignal_two_param_int_str_handler)
self.mySignal_two_param[str, str].connect(self.mySignal_two_param_str_str_handler) def onClicked(self):
# 发送信号
self.mySignal_no_aram.emit()
self.mySignal_int.emit(1)
self.mySignal_int_or_str[int].emit(2)
self.mySignal_int_or_str[str].emit('abc')
self.mySignal_two_param[int, str].emit(3, 'def')
self.mySignal_two_param[str, str].emit('abc', 'def') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
使用自定义参数
import sys
from functools import partial
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
button1 = QPushButton(self)
button1.setText('button1')
button1.move(10, 10)
button2 = QPushButton(self)
button2.setText('button2')
button2.move(10, 50) # button1.clicked.connect(lambda: self.onClicked(button1))
# button2.clicked.connect(lambda: self.onClicked(button2))
# 等价
button1.clicked.connect(partial(self.onClicked, button1))
button2.clicked.connect(partial(self.onClicked, button2)) def onClicked(self, btn):
print("%s" % btn.text()) if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
使用装饰器定义信号与槽
import sys
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
button = QPushButton(self)
button.setText('点击') # 设置发送者名称
button.setObjectName('button')
# 实现绑定
QtCore.QMetaObject.connectSlotsByName(self) # 槽函数命名规则:on_发送者名称_发射信号名称(self, param)
@QtCore.pyqtSlot()
def on_button_clicked(self):
print('you clicked button') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
PyQt5事件处理的更多相关文章
- Ubuntu 14.04下搭建Python3.4 + PyQt5.3.2 + Eric6.0开发平台
引言 找了很多Python GUI工具集,还是觉得PyQt比较理想,功能强大跨平台,还支持界面设计器.花一天时间折腾了Ubuntu14.04(32位)+ Python3.4 + Qt5.3.2 + P ...
- PyQt5多点触控写字板实现及困惑
Qt支持程序多点触控,就想使用PyQt5做一个触控画板,经过几番周折,查阅了TouchEvent官方文档,又参考了一篇QT for Android的例子,采用eventfilter过滤器来识别触屏事件 ...
- pyqt5之简单窗口的创建
在学完tkinter后,发现tkinter在布局方面特别的不方便(Tkinter资料:http://effbot.org/tkinterbook/tkinter-index.htm),因此学习pyqt ...
- PyQt5基础应用一
一.PyQt5基础 1.1 创建窗口 import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__ ...
- pyqt5 -——基本功能(HelloWorld)
一. 简单窗口 这个简单的小例子展示的是一个小窗口.但是我们可以在这个小窗口上面做很多事情,改变大小,最大化,最小化等,这需要很多代码才能实现.这在很多应用中很常见,没必要每次都要重写这部分代码,Qt ...
- 五、Pyqt5事件、信号和槽
PyQt中提供了两种针对事件处理的机制:一种是事件,另一种则是信号和槽. 一.事件 事件处理在PyQt中是比较底层的,常用的事件有键盘事件.鼠标事件.拖放事件.滚轮事件.定时事件.焦点事件.进入和离开 ...
- 一、PyQt5基础概念与安装配置
一.初识PyQt5 对于桌面程序开发,用户图形界面(GUI)的设计非常重要.一款美观.易用的用户界面可以很大程度上提高对使用这的友好度.由于Python最初是作为脚本语言开发,并没有GUI功能.但Py ...
- pyQT4和pyQT5的主要模块介绍
下面简单介绍一下pyQT4和pyQT5的主要模块 pyQT4 的主要模块 QtCore 模块包括了核心的非GUI功能,该模块用来对时间.文件.目录.各种数据类型.流.网址.媒体类型.线程或进程进行处理 ...
- PyQt5简介及demo
PyQt5说明 pyqt5是一套Python绑定Digia QT5应用的框架.它可用于Python 2和3.本教程使用Python 3.Qt库是最强大的GUI库之一.pyqt5的官方网站http:// ...
随机推荐
- docker已运行容器里的时区修改
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 或者 cp /usr/share/zoneinfo/Asia/Shanghai ...
- Mysql Workbench中EER Diagram逆向生成表
选择链接 选择需要生成的表
- Spring Cloud面试题万字解析(2020面试必备)
1.什么是 Spring Cloud? Spring cloud 流应用程序启动器是 于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成.Spring cloud Tas ...
- linux网络编程-一个简单的线程池(41)
有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带来的开销,我们可以使用线程池 1.线程池拥有若干个线程,是线程的集合,线程池中的线程数目有严格的要求,用于执行大量的相对短 ...
- 深度学习论文翻译解析(八):Rich feature hierarchies for accurate object detection and semantic segmentation
论文标题:Rich feature hierarchies for accurate object detection and semantic segmentation 标题翻译:丰富的特征层次结构 ...
- django项目常见报错集
1.mysqlclient 目前不支持高版本python3 django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or new ...
- MySQL 百万级数据量分页查询方法及其优化
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...
- 深入理解letter-spacing,word-spacing的对比区别
letter-spacing lletter-spacing 属性增加或减少字符间的空白(字符间距). 该属性定义了在文本字符框之间插入多少空间.由于字符字形通常比其字符框要窄,指定长度值时,会调整字 ...
- thinkphp将对象变成一维数组?
thinkphp使用select查询出的数据为二维数组,如果想将二维数组转一维,可以使用: $x为二维数组对象 php版本要大于5.5.0 $userid_array = array_column($ ...
- vue.js之常操作(实例)
听说大家都开始用react.vue这些MVVM框架了,为了不落后,还是学学吧!(之前只对angular了解一点,时间一长,也忘得差不多了,所以学习vue相当于从小白开始) 从vue.js官网看一下,先 ...