软硬件环境
- windows 10 64bit
- Miniconda3 with python 3.7.1
- PyQt5
前言
信号(Signal)和槽(Slot)是Qt编程中对象间通讯的机制,在编写PyQt5程序时,不可能离得开信号和槽。在Qt中,每一个QObject对象,包括PyQt中所有继承自QWidget的控件(因为它们都是QObject的子对象)都支持signal和slot机制。
signal和slot绑定
还是以之前的PyQt5工程为例
self.pushButton.clicked.connect(self.button_clicked)
上面的代码表明当按钮pushButton(QPushButton是QWidget的子类)被点击(释放clicked信号)时,slot(方法button_clicked)会被执行。
同一signal绑定多slot
PyQt5允许一个signal同时绑定多个slot,如
from PyQt5.QtWidgets import QPushButton
self.pushButton.clicked.connect(self.button_clicked)
self.pushButton.clicked.connect(self.button_clicked_2)
从执行结果上看,slot执行的顺序是跟绑定的顺序一样的,即先绑先执行。另外对于多个signal绑定同一slot的情况,比较容易理解,就不多说
一个signal绑定另一个signal
还有种特殊的情况是signal和signal的绑定,这里假设还有一个QPushButton pushButton1,我们让它的clicked信号和pushButton的信号clicked相绑定,如下
from PyQt5.QtWidgets import QPushButton
self.pushButton.clicked.connect(self.button_clicked)
self.pushButton1.clicked.connect(self.pushButton.clicked)
signal的解绑
PyQt5提供了disconnect方法来进行解绑
from PyQt5.QtWidgets import QPushButton
self.pushButton1.clicked.disconnect(self.pushButton.clicked)
self.pushButton.clicked.disconnect(self.button_click_2)
自定义signal
PyQt5提供了QtCore.pyqtSignal函数来产生一个signal,之后就是熟悉的绑定操作了,看个实例就清楚了
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import pyqtSignal
class EmitSignal(QWidget):
def __init__(self):
super(EmitSignal,self).__init__()
self.customSignal = pyqtSignal()
def emitCustomSignal(self):
self.customSignal.emit()
发送带参数的signal
经常需要在某个signal发送时附带相应的数据,实际上就是传参,然后在slot方法中接收传递过来的数据,这样就可以非常灵活地实现一些业务逻辑
首先是生成一个signal
transcoding_thread_status = pyqtSignal(object)
然后将signal和slot方法绑定
self.transcoding_thread_status.connect(self.slotShowTransThreadStatus)
slot方法接收数据
def slotShowTransThreadStatus(something):
print(something)
最后来看看,signal emit时是怎么实现的
self.transcoding_thread_status.emit("Hello")
至此数据就传递成功了,就是这么简单。
以上是传递一个参数,那如果我需要传递2个呢,是不是也可以用上面的方法呢?思路是一样的,细节做一点小修改就好了。
transcoding_thread_status = pyqtSignal(str,str)
如果传递的数据类型是整形的话,就换成int,对应的slot方法也要跟着修改
def slotShowTransThreadStatus(something,anything):
print('something={}, anything={}'.format(something, anything))
发送信号时,就跟上2个参数
self.transcoding_thread_status.emit("Hello","world")
类似的,如果需要传递更多参数,请依葫芦画瓢。
备注
为了便于保存记录,在Github创建了一个工程,地址是: https://github.com/xugaoxiang/learningPyQt5,后续会把所有的代码、文档以及博文链接都放在上面。