在 PyQt5 中使用全局信号
Qt 的信号和槽机制在不同界面间交换控制和消息,是一个很有用的机制。有时为了在不同界面对象甚至不同线程间使用这一机制,需要建立全局的信号变量。
需要注意的是:不能简单地用 signal_inst = pyqtSignal()
建立信号实例。信号实例必须是一个继承自 QObject 类的类成员,否则运行 connect 时会报错,无法正常工作。因此,建立和使用信号实例须经历以下步骤:
1. 定义一个继承自 PyQt5.QtCore.QObject 的类;
2. 在类中定义一个或多个 pyqtSignal 类成员;
3. 用定义的类生成一个全局变量;
4. 在发送信号(emit)和接收信号(connect)的模块中,引入该全局变量;
5. 按照正常的方式使用信号和槽。
下面是全局变量定义文件,文件名为global_var.py,实现上述的 1、2、3 三个步骤:
from PyQt5.QtCore import pyqtSignal, QObject
# 定义派生自 QObject 的类
class SignalGroup(QObject):
# 在类中定义信号
repaint_signal = pyqtSignal(str)
# 定义全局变量,供发送和接收程序调用
signal_object = SignalGroup()
下面是发送和接收信号的测试程序文件,文件名为 any_test.py:
# 引入全局变量 signal_object
from global_vars import signal_object
# 这是发送信号的类
class A:
def __init__(self, s=''):
super().__init__()
# self.sig_string 是用于发送的参数
self.sig_string = s
# 发送方法
def send_sig(self):
# 发送信号
signal_object.repaint_signal.emit(self.sig_string)
# 这是接收信号的类
class B:
def __init__(self, inst_name=""):
super().__init__()
self.test_string = inst_name + " get signal: "
# 定义槽
signal_object.repaint_signal.connect(self.test_sig)
# 接收方法,s 是接收到的参数
def test_sig(self, s):
print(self.test_string + s)
if __name__ == "__main__":
# 发送对象实例
a = A('signal from a')
# 两个接收对象实例
b = B("inst b")
b1 = B("inst b1")
a.send_sig()
在主程序中,我们生成了一个发送类(A)的实例(a),两个接收类(B)的实例(b,b1),运行any_test.py,得到如下输出:
inst b get signal: signal from a
inst b1 get signal: signal from a
Process finished with exit code 0
从输出可以看出,两个接收实例都收到了发送实例发出的信号。