Pyqt 信号(signal)和槽函数(slot)
信号(signal):就是在特定情况下被发射(emit)的一种通告
槽函数(slot):对信号(signal)相应的函数, 接收某个对象发送的信号,执行某种操作。槽函数和普通函数的区别就是可与 信号 关联。
在Qt中,每一个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制。当信号发射时,连接的槽函数将会自动执行。在PyQt 5中信号与槽通过object.signal.connect()方法连接。
PyQt的窗口控件类中有很多内置信号,开发者也可以添加自定义信号。信号与槽具有如下特点。
- 一个信号可以连接多个槽。
- 一个信号可以连接另一个信号。
- 信号参数可以是任何Python类型。
- 一个槽可以监听多个信号。
- 信号与槽的连接方式可以是同步连接,也可以是异步连接。
- 信号与槽的连接可能会跨线程。
- 信号可能会断开。
示例如下,截取了部分自己的代码, 注意在自定义信号signal时要在属性中定义, 不要在__init__中定义
from PyQt5 import QtCore
class StartClient(QtCore.QObject):
signal_progress = QtCore.pyqtSignal(int)
signal_log = QtCore.pyqtSignal(str)
signal_clear_log = QtCore.pyqtSignal()
signal_status = QtCore.pyqtSignal(str)
signal_lineEdit_ip = QtCore.pyqtSignal(str)
signal_client_id = QtCore.pyqtSignal(str)
signal_devuaid = QtCore.pyqtSignal(str)
signal_iccid = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.groupBox = None
self.lineEdit_ip = None
self.lineEdit_devuaid = None
self.lineEdit_client_id = None
self.lineEdit_iccid = None
self.progressBar = None
self.file_log = None
self.pushButton_log = None
self.textEdit_log = None
self.lineEdit_status = None
# connect slot
self.signal_progress[int].connect(self.__slot_set_progress_bar_value)
self.signal_log[str].connect(self.__slot_write_log)
self.signal_status[str].connect(self.__slot_set_status)
self.signal_lineEdit_ip[str].connect(self.__slot_set_ip)
self.signal_client_id[str].connect(self.__slot_set_client_id)
self.signal_devuaid[str].connect(self.__slot_set_devuaid)
self.signal_iccid[str].connect(self.__slot_set_iccid)
self.device_ip = ""
self.devuaid = ""
self.client_id = ""
self.iccid = ""
self.password = ""
self.sign_key = ""
self.mac = ""
def __slot_set_iccid(self, text=""):
if self.lineEdit_iccid is not None:
self.lineEdit_iccid.setText(text)
self.iccid = text
def set_iccid(self, text=""):
if self.signal_iccid is not None:
self.signal_iccid.emit(text)
def set_iccid2(self, text=""):
self.iccid = text
示例中,槽函数__slot_set_iccid()同时给两个地方赋了值, 值得注意的时如果使用了signal和slot这种方式给self.iccid复制,时间上不如方法set_iccid2(),因为当发出信号后,到槽函数接受到信号开始处理时需要一段时间, 这段时间再调试时可能感觉不出来,但在实际运行中,就需要确认槽函数已经接受的信号并且已经处理完成,之后再能使用self.iccid的值