徐高翔的个人网站

PyQt5系列教程(五)信号和槽

2017-06-11

软硬件环境

  • windows 10 64bit
  • Miniconda3 with python 3.7.1
  • PyQt5

前言

信号(Signal)和槽(Slot)是Qt编程中对象间通讯的机制,在编写PyQt5程序时,不可能离得开信号和槽。在Qt中,每一个QObject对象,包括PyQt中所有继承自QWidget的控件(因为它们都是QObject的子对象)都支持signalslot机制。

signal和slot绑定

还是以之前的PyQt5工程为例

1
self.pushButton.clicked.connect(self.button_clicked)

上面的代码表明当按钮pushButton(QPushButtonQWidget的子类)被点击(释放clicked信号)时,slot(方法button_clicked)会被执行。

同一signal绑定多slot

PyQt5允许一个signal同时绑定多个slot,如

1
2
3
4
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

还有种特殊的情况是signalsignal的绑定,这里假设还有一个QPushButton pushButton1,我们让它的clicked信号和pushButton的信号clicked相绑定,如下

1
2
3
4
from PyQt5.QtWidgets import QPushButton

self.pushButton.clicked.connect(self.button_clicked)
self.pushButton1.clicked.connect(self.pushButton.clicked)

signal的解绑

PyQt5提供了disconnect方法来进行解绑

1
2
3
4
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,之后就是熟悉的绑定操作了,看个实例就清楚了

1
2
3
4
5
6
7
8
9
10
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

1
transcoding_thread_status = pyqtSignal(object)

然后将signalslot方法绑定

1
self.transcoding_thread_status.connect(self.slotShowTransThreadStatus)

slot方法接收数据

1
2
def slotShowTransThreadStatus(something):
print(something)

最后来看看,signal emit时是怎么实现的

1
self.transcoding_thread_status.emit("Hello")

至此数据就传递成功了,就是这么简单。

以上是传递一个参数,那如果我需要传递2个呢,是不是也可以用上面的方法呢?思路是一样的,细节做一点小修改就好了。

1
transcoding_thread_status = pyqtSignal(str,str)

如果传递的数据类型是整形的话,就换成int,对应的slot方法也要跟着修改

1
2
def slotShowTransThreadStatus(something,anything):
print('something={}, anything={}'.format(something, anything))

发送信号时,就跟上2个参数

1
self.transcoding_thread_status.emit("Hello","world")

类似的,如果需要传递更多参数,请依葫芦画瓢。

备注

为了便于保存记录,在Github创建了一个工程,地址是: https://github.com/xugaoxiang/learningPyQt5,后续会把所有的代码、文档以及博文链接都放在上面。

本文链接 https://xugaoxiang.com/2017/06/11/PyQt5系列教程(五)信号和槽/

推荐文章(由hexo文章推荐插件驱动)

使用支付宝打赏
使用微信打赏

请博主喝咖啡!