五、Pyqt5事件、信号和槽
PyQt中提供了两种针对事件处理的机制:一种是事件,另一种则是信号和槽。
一、事件
事件处理在PyQt中是比较底层的,常用的事件有键盘事件、鼠标事件、拖放事件、滚轮事件、定时事件、焦点事件、进入和离开事件(光标移入控件或者移出),移动事件(窗口位置变化),显示和隐藏事件,窗口事件(窗口是否为当前窗口)、以及常见的Qt事件:Socket事件、剪贴板事件、文字改变事件,布局改变事件等。
针对这些事件,PyQt提供了多种事件处理和过滤方法,其中最常用的有两种:
(1)重写事件具体的函数(例如:mousePressEvent()/keyPressEvent()....)
(2)重新实现QObject.event()一般用在PyQt没有提供该事件的处理函数的情况下,即添加一个新的事件;
1.1 重写事件
import sys,os
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication,QMessageBox
from PyQt5.QtGui import QIcon path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class MyWindow(QWidget): def __init__(self):
super(MyWindow, self).__init__()
self.initUI() def initUI(self):
self.setGeometry(300, 300, 300, 250)
self.setWindowTitle('重写事件示例')
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path)) def closeEvent(self, QCloseEvent):
'''
重写closeEvent方法,关闭窗口时触发
'''
reply = QMessageBox.question(self,'本程序',"是否要退出程序?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.Yes:
QCloseEvent.accept()
else:
QCloseEvent.ignore() def keyPressEvent(self, QKeyEvent):
'''
重写keyPressEvent事件,按下ESC就会退出程序
'''
if QKeyEvent.key() == Qt.Key_Escape:
self.close() if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
重写事件示例
这段代码里重写了keyPressEvent和closeEvent两个事件。实现了两个功能:(1)按下ESC是可退出关闭窗口;(2)关闭当前窗口时,弹出对话框。
效果图如下:

在pycharm中编辑时,我们可以发现,QWidget类下虽然有该keyPressEvent和closeEvent方法,但并没有编写有意义的内容。
1.2 创建新事件
可参考前面小节的center(),不再详述。
除上述内容外,再对三个概念加以学习,即事件对象、事件发送。
事件对象时python用来描述一系列自身属性的对象。
import sys,os
from PyQt5.QtWidgets import QApplication,QWidget,QGridLayout,QLabel
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class MyWindow(QWidget): def __init__(self):
super().__init__()
self.initUI() def initUI(self):
self.setGeometry(600,300,350,250)
self.setWindowTitle('信号和槽')
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path)) grid = QGridLayout()
grid.setSpacing(10) x=0
y=0
self.text = "x:{},y:{}".format(x,y)
self.label = QLabel(self.text,self)
grid.addWidget(self.label,0,0,Qt.AlignTop) self.setMouseTracking(True) #开启鼠标追踪
self.setLayout(grid) def mouseMoveEvent(self, QMouseEvent):
x = QMouseEvent.x()
y = QMouseEvent.y()
text = "x:{},y:{}".format(x, y)
self.label.setText(text) if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
事件对象示例
在这个示例中,我们再label里显示鼠标的坐标。mouseMoveEvent方法下的QMouseEvent即鼠标移动的事件对象,也就是需要捕捉的信号来源。

事件发送是在程序设计与调试时,我们需要知道是哪一个控件发送了信号,利用PyQt5中的sender()方法可以实现。
import sys,os
from PyQt5.QtWidgets import QMainWindow,QApplication,QPushButton
from PyQt5.QtGui import QIcon path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class MyWindow(QMainWindow): def __init__(self):
super().__init__()
self.initUI() def initUI(self):
self.setGeometry(600,300,300,260)
self.setWindowTitle('事件发送')
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path)) btn1 = QPushButton('按钮一',self)
btn2 = QPushButton('按钮二',self) btn1.move(30,50)
btn2.move(150,50) btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.buttonClicked) self.statusBar() def buttonClicked(self):
sender = self.sender()
self.statusBar().showMessage(sender.text() + '被按下') if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
事件发送示例
sender()方法可以返回发送信号的控件名称。这在我们调试时可以起到极大的辅助作用。方便快速了解程序背后的设计思路。

二、信号和槽
信号(Signal)和槽(Slot)是Qt中的核心机制,也是在PyQt编程中对象之间进行通信的机制。在Qt中,每个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制。当信号发射时,连接的槽函数将会自动执行。在PyQt5中信号与槽通过object.signal.connect()方法连接。
使用时,既可以自定义信号,也可以使用pyqt内置信号。信号与槽具有以下几个特点:
- 一个信号可以连接多个槽;
- 一个信号也可以连接另一个信号;
- 一个槽可以监听多个信号;
- 信号与槽的连接可能同步或者异步,还可能跨线程连接;
- 信号也可能断开。
除此之外,还有几个常用的操作方法需要说明:
- connect()方法可以将信号与槽函数连接。注意这里的槽函数不能加括号(后面会讲到);
- disconnect可以将接触信号与槽的连接;
- emit()可以发射信号
- 如果需要自定义信号,可以使用PyQt5.QtCore下的pyqtSignal方法。
import sys,os
from PyQt5.QtCore import pyqtSignal,QObject
from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5.QtGui import QIcon path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class Communicate(QObject):
closeApp = pyqtSignal() class MyWindow(QMainWindow): def __init__(self):
super(MyWindow, self).__init__()
self.initUI() def initUI(self):
self.setGeometry(600,300,500,400)
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
self.setWindowTitle('信号发送') self.c = Communicate()
self.c.closeApp.connect(self.close) def mousePressEvent(self, *args, **kwargs):
self.c.closeApp.emit() if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
信号与槽
在这个示例中,我们创建了一个closeApp的信号,该信号会在鼠标按下时触发。且该事件与QMainwindow绑定。
class Communicate(QObject):
closeApp = pyqtSignal()
这里,我们创建了一个Communicate类,并在该类下创建了信号。
self.c = Communicate()
self.c.closeApp.connect(self.close)
首先将communicate()类示例化给self.c。然后将closeApp信号与窗口的close()方法连接。
def mousePressEvent(self, *args, **kwargs):
self.c.closeApp.emit()
点击鼠标按键时,emit()方法会将closeApp信号发射。
五、Pyqt5事件、信号和槽的更多相关文章
- PyQT5:信号和槽
PyQT5:信号和槽 信号和槽 Qt的主要特征之一是它使用信号和插槽在对象之间进行通信. 当潜在的事件发生时,会发出一个信号.插槽是可调用的Python,如果将信号连接到插槽,则在发出信号时将调用该插 ...
- pyqt5核心-信号与槽(第二弹)
果: from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.s ...
- PyQt5中的信号与槽,js 与 Qt 对象之间互相调用
一.PyQt中的信号与槽 信号(Signal)和槽(Slot)是Qt中的核心机制,用在对象之间互相通信.在Qt中每个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject ...
- PyQt5(3)——信号和槽初探
信号和槽是QT的核心机制(当信号发射时,链接的槽函数会自动执行) 在pyqt5中信号和槽通过 QObject.signal.connect()链接. QObject类或子类(QWidget)派生的类都 ...
- Qt对象模型之一:信号和槽
一.信号和槽机制概述 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种发出是没有目 ...
- PyQt5信号与槽详解
1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...
- pyqt5信号与槽2
信号和槽与类的属性和方法在层次上是相同的,同属与一个类的特征. 信号的定义由工厂函数生成: signal=PyQt5.QtCore.pyqtSignal(types[, name[, result[, ...
- [ PyQt入门教程 ] PyQt5信号与槽
信号和槽是PyQt编程对象之间进行通信的机制.每个继承自QWideget的控件都支持信号与槽机制.信号发射时(发送请求),连接的槽函数就会自动执行(针对请求进行处理).本文主要讲述信号和槽最基本.最经 ...
- PyQt5信号与槽关联的两种方式
目录 通过QtDesigner 手动关联的方式 通过QtDesigner 单击菜单栏切换到信号槽编辑模式 单击控件并拖动鼠标到信号的接收对象上,一般为对话框自己,松开鼠标弹出信号和槽选择框 选中cli ...
随机推荐
- Django整理1
基本结构 │ db.sqlite3 ----------sqlie3数据库 │ manage.py │ ├─logres │ │ admin.py 后台,可以用很少量的代码就拥有一个强大的后台. │ ...
- 关于新学期Python的一点见解
首先很高兴选到了Python,之前学习过c语言,不过学的不大好. 我希望此次课程能够教会我们如何运用Python解决生活中的一些小问题,或者可以解决其他学科上的一些问题,当然有关人工智能方面的最好. ...
- PHP超全局变量$_SERVER分析
$_SERVER 是一个包含了诸如头信息(header).路径(path).以及脚本位置(script locations)等等信息的数组.这个数组中的项目由 Web 服务器创建.不能保证每个服务器都 ...
- 地址栏输入url按回车发生了什么
浏览器向DNS服务器(先查找缓存)查找输入URL对应的IP地址 DNS服务器返回对应的IP地址 浏览器根据IP地址与目标web服务器在80端口上建立TCP连接 浏览器获取请求页面的html代码 浏览器 ...
- DLL 函数中使用结构体指针作函数参数(C# 调用 C++ 的 DLL)
存在的问题: 问题1:C++ 与 C# 同样定义的结构体在内存布局上有时并不一致: 问题2:C# 中引入了垃圾自动回收机制,其垃圾回收器可能会重新定位指针所指向的结构体变量. 解决方案: 问题1方案: ...
- Python module ---- os
os 模块Python标准库中的一个用于访问操作系统功能的模块,使用OS模块中提供的接口,可以实现跨平台访问.提供了一个统一的操作系统接口函数, 这些接口函数通常是平台指定的,os 模块能在不同操作系 ...
- vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)
vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了,差ddf那部分,因为考虑到自己要换 ...
- Lock和Static使用说明和区别
private static object lockInsertObj = new object(); lock (lockInsertObj){--写代码} 1.静态方法与非静态方法 a.静态方法的 ...
- ajax、json、jsonp
这章分享下ajax.json.jsonp的学习记录,不得不说这真是些令人激动的技术. 推荐文章: https://segmentfault.com/a/1190000012469713 http:// ...
- 初学python笔记---列表
---恢复内容开始--- 1.列表的格式:用方括号([])来表示的,逗号来分隔元素,下标从0开始 2.根据下标来查看列表中元素,当索引为-1时,显示的是最后一个元素 print(a[0])-----1 ...