3.PyQt5程序自定义信号
3.1信号与槽的特定
在PyQt5中信号与槽的特点:
-
一个信号可以关联多个槽函数
-
一个信号可以关联其他信号
-
信号的参数可以是任意的Python数据类型
-
一个槽函数可以与多个信号关联
-
关联可以分为同步的或者异步的
-
在不同的线程之间可以建立关联
-
信号与槽可以断开关联
3.2自定义信号
在使用PyQt5进行程序设计时,我们可以使用PyQt5.QtCore.pyqtSignal给类定义新的信号。如果要给类定义自定义信号,该类必须是QObject的子类,同时信号必须定义为类属性。pyqtSignal句法:
pyqtSignal(types[, name[, revision=0[, argiments=[]]]])
其中:
参数types表示参数类型。
其余参数都是可选项,一般不会使用。
信号的函数:
-
connect() 关联槽函数
-
disconnect() 断开关联
-
emit() 发射信号
3.3自定义信号示例
本例通过给类定义自定义信号来演示自定义信号的使用。
# coding: utf-8 import sys from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot import json class Student(): def __init__(self, name, sex): self.__name = name self.__sex = sex def getSex(self): return self.__sex class Class(QObject): # 定义自定义信号 classNameChanged = pyqtSignal(str) studentsChanged = pyqtSignal([int], [str]) def __init__(self, parent=None): super().__init__(parent) self.__students = [] def setClassName(self, class_name): self.__className = class_name # 发射信号 self.classNameChanged.emit(self.__className) def addStudent(self, student): self.__students.append(student) # 发射信号 self.studentsChanged[int].emit(len(self.__students)) result = {'男': 0, '女': 0} for student in self.__students: if student.getSex() == '男': result['男'] += 1 if student.getSex() == '女': result['女'] += 1 # 发射信号 self.studentsChanged[str].emit(json.dumps(result)) class App(QObject): # 槽函数 @pyqtSlot(str) def do_classNameChanged(self, className): print("班级:" + className) # 槽函数 @pyqtSlot(int) def do_studentsChanged_int(self, num): print("班级总人数:" + str(num)) # 槽函数 @pyqtSlot(str) def do_studentsChanged_str(self, sData): data = json.loads(sData) print("男生人数:" + str(data['男'])) print("女生人数:" + str(data['女'])) if __name__ == '__main__': s1 = Student('赵XX', '女') s2 = Student('陈XX', '女') s3 = Student('李XX', '男') s4 = Student('秦XX', '男') s5 = Student('姜XX', '女') s6 = Student('刘XX', '男') s7 = Student('王XX', '男') a = App() c = Class() # 建立信号与槽的关联 c.classNameChanged.connect(a.do_classNameChanged) c.studentsChanged[int].connect(a.do_studentsChanged_int) c.studentsChanged[str].connect(a.do_studentsChanged_str) c.setClassName('计算机2101班') c.addStudent(s1) c.addStudent(s2) c.addStudent(s3) c.addStudent(s4) c.addStudent(s5) # 解除信号与槽的关联 c.studentsChanged[int].disconnect(a.do_studentsChanged_int) c.studentsChanged[str].disconnect(a.do_studentsChanged_str) c.addStudent(s6) c.addStudent(s7)
运行程序,输出的结果如下:
班级:计算机2101班 班级总人数:1 男生人数:0 女生人数:1 班级总人数:2 男生人数:0 女生人数:2 班级总人数:3 男生人数:1 女生人数:2 班级总人数:4 男生人数:2 女生人数:2 班级总人数:5 男生人数:2 女生人数:3
在使用信号与槽的时候,需要特别注意的几点:
1.PyQt5中类的内建overload型信号,一般只选择其中一种信号编写槽函数,如果使用非默认参数类型的信号,槽函数需要使用@pyqtSlot()修饰符声明参数类型。
2.自定义信号时,尽量不定义overload型信号。