13. 自定义信号

PyQt5中,信号与槽使用的一些特点:

- 一个信号可以关联多个槽函数

- 一个信号可以关联其他信号

- 信号的参数可以是任何python数据类型

- 一个槽函数可以和多个信号关联

- 关联可以是直接的(同步),也可以是排队的(异步)

- 可以在不同线程之间建立关联

- 信号与槽也可以断开关联

1. pyqtSignal()

# 自定义的信号类必须是QObject类的子类
# 使用PyQt5.QtCore.pyqtSignal()为一个类定义新的信号
# 信号定义为类属性
# connect()关联槽函数,disconnect()断开关联,emit()发射信号

 1 import sys
 2 from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal
 3 
 4 class Human(QObject):
 5     # 定义一个带str类型的信号
 6     nameChanged = pyqtSignal(str)
 7     # overload型信号有两种参数,int和str
 8     ageChanged = pyqtSignal([int],[str])
 9 
10     def __init__(self,name='jim',age=10,parent=None):
11         super().__init__(parent)
12         self.setAge(age)
13         self.setName(name)
14 
15     def setAge(self,age):
16         self.__age = age
17         self.ageChanged.emit(self.__age)    #发射int参数信号
18         if age<=18:
19             ageInfo = '你是少年'
20         elif 18<age<=35:
21             ageInfo = '你是年轻人'
22         elif 35<age<=55:
23             ageInfo = '你是中年人'
24         elif 55<age<=85:
25             ageInfo = '你是老年人'
26         elif age>85:
27             ageInfo = '你是老寿星'
28         self.ageChanged[str].emit(ageInfo)      # 发射str参数信号
29 
30     def setName(self,name):
31         self.__name = name
32         self.nameChanged.emit(self.__name)
33 
34 
35 class Responsor(QObject):
36     @pyqtSlot(int)
37     def do_ageChanged_int(self,age):
38         print('你的年龄是:',str(age))
39     @pyqtSlot(str)
40     def do_ageChanged_str(self,ageInfo):
41         print(ageInfo)
42 
43     @pyqtSlot(str)
44     def do_nameChanged(self,name):
45         print('Hello',name)
46 
47 
48 if __name__ == '__main__':
49     print('创建对象时:')
50     boy = Human('Boy', 16)
51     res = Responsor()
52     # 信号关联槽
53     boy.nameChanged.connect(res.do_nameChanged)
54     # overload信号,两个槽函数不能同名,关联时需要给信号加参数区分
55     boy.ageChanged.connect(res.do_ageChanged_int)
56     boy.ageChanged[str].connect(res.do_ageChanged_str)
57 
58     print('建立关联:')
59     boy.setAge(35)      # 发射两个ageChanged信号
60     boy.setName('lily') # 发射nameChanged信号
61 
62     # 断开关联
63     boy.ageChanged[str].disconnect(res.do_ageChanged_str)
64     print('断开关联:')
65 
66     boy.setAge(20)  # 发射两个ageChanged信号
67     boy.setName('lucy')
View Code

  - Human继承QObject,定义2个信号:

    - nameChanged = pyqtSignal(str)

    - ageChanged = pyqtSignal([int],[str])  overload型信号,两种类型参数

  - 信号发射emit(),当类的某个状态发生变化,需要通知外部发生了这种变化时,发射相应信号

    - self.nameChanged.emit(self.__name)  当变量self.__name发生变化时,发射信号并传递参数

    - overload型信号发射两次信号要标识好参数

      * self.ageChanged.emit(self.__age)

      * self.ageChanged[str].emit(ageInfo)

2. 信号与槽关联

  - 定义Responsor类继承QObject,定义3个函数用于与Human类的实例对象的信号建立关联

  - ageChanged信号是overload类型信号,有两种类型参数,需要定义两个槽函数进行关联

    - do_ageChanged_int

    - do_ageChanged_str

    - do_nameChanged

  - @pyqtSlot() 用于声明槽函数的参数类型

  - 需要在创建类的具体实例后再进行信号与槽的关联 connect

    - boy.nameChanged.connect(res.do_nameChanged)

    - boy.ageChanged.connect(res.do_ageChanged_int)

    - boy.ageChanged[str].connect(res.do_ageChanged_str)

  - 断开信号与槽的关联 disconnect

    - boy.ageChanged[str].disconnect(res.do_ageChanged_str)

* PyQt5中的类的内建 overload型信号,一般只为其中一种信号编写槽函数

* 自定义信号时,尽量不要定义overload型信号

posted @ 2020-12-03 15:14  GOgo学习  阅读(198)  评论(0)    收藏  举报