pyqt signal slot thread 多线程



目录(?)[+]

        信号(singal)与槽(slot)用于对象相互通信,信号:当某个对象的某个事件发生时,触发一个信号,槽:响应指定信号的所做的反应,其实信号槽类似于.NET里面的委托、事件,比如Repeater控件类,当行数据绑定后,触发一个ItemDataBound事件,不管使用者使用会监听该事件并做额外处理,其控件类内部都会触发该事件,这种机制很多程度提高了类的封装性和完整性。
  PyQt的窗体控件类已经有很多的内置信号,开发者也可以添加自己的自定义信号,信号槽有如下特点:
    - 一个信号可以连接到许多插槽。
    - 一个信号也可以连接到另一个信号。
    - 信号参数可以是任何Python类型。
    - 一个插槽可以连接到许多信号。
    - 连接可能会直接(即同步)或排队(即异步)。
    - 连接可能会跨线程。
    - 信号可能会断开

  (以上几条特点翻译于官方文档),接下来,我将以若干个实例,来体现以上几个特点。

内置信号槽的使用

[python]   view plain  copy
  1. from PyQt5.QtWidgets import *  
  2. from PyQt5.QtCore import *  
  3.     
  4. def sinTest():  
  5.     btn.setText("按钮文本改变")  
  6.     
  7. app = QApplication([])  
  8.     
  9. main = QWidget()  
  10. main.resize(200,100)  
  11. btn = QPushButton("按钮文本",main)  
  12. ##按钮btn的内置信号连接名为sinTest的槽  
  13. btn.clicked.connect(sinTest)  
  14. main.show()  
  15.     
  16. app.exec_()  

自定义信号槽的使用

[python]   view plain  copy
  1. class SinClass(QObject):  
  2.         
  3.     ##声明一个无参数的信号  
  4.     sin1 = pyqtSignal()  
  5.         
  6.     ##声明带一个int类型参数的信号  
  7.     sin2 = pyqtSignal(int)  
  8.         
  9.     ##声明带一个int和str类型参数的信号  
  10.     sin3 = pyqtSignal(int,str)  
  11.     
  12.     ##声明带一个列表类型参数的信号  
  13.     sin4 = pyqtSignal(list)  
  14.     
  15.     ##声明带一个字典类型参数的信号  
  16.     sin5 = pyqtSignal(dict)  
  17.     
  18.     ##声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号  
  19.     sin6 = pyqtSignal([int,str], [str])  
  20.         
  21.     def __init__(self,parent=None):  
  22.         super(SinClass,self).__init__(parent)  
  23.     
  24.         ##信号连接到指定槽  
  25.         self.sin1.connect(self.sin1Call)  
  26.         self.sin2.connect(self.sin2Call)  
  27.         self.sin3.connect(self.sin3Call)  
  28.         self.sin4.connect(self.sin4Call)  
  29.         self.sin5.connect(self.sin5Call)  
  30.         self.sin6[int,str].connect(self.sin6Call)  
  31.         self.sin6[str].connect(self.sin6OverLoad)  
  32.     
  33.         ##信号发射  
  34.         self.sin1.emit()  
  35.         self.sin2.emit(1)  
  36.         self.sin3.emit(1,"text")  
  37.         self.sin4.emit([1,2,3,4])  
  38.         self.sin5.emit({"name":"codeio","age":"25"})  
  39.         self.sin6[int,str].emit(1,"text")  
  40.         self.sin6[str].emit("text")  
  41.             
  42.     def sin1Call(self):  
  43.         print("sin1 emit")  
  44.     
  45.     def sin2Call(self,val):  
  46.         print("sin2 emit,value:",val)  
  47.     
  48.     def sin3Call(self,val,text):  
  49.         print("sin3 emit,value:",val,text)  
  50.     
  51.     def sin4Call(self,val):  
  52.         print("sin4 emit,value:",val)  
  53.             
  54.     def sin5Call(self,val):  
  55.         print("sin5 emit,value:",val)  
  56.     
  57.     def sin6Call(self,val,text):  
  58.         print("sin6 emit,value:",val,text)  
  59.     
  60.     def sin6OverLoad(self,val):  
  61.         print("sin6 overload emit,value:",val)  
  62.     
  63. sin = SinClass()  
运行结果:
sin1 emit
sin2 emit,value: 1
sin3 emit,value: 1 text
sin4 emit,value: [1, 2, 3, 4]
sin5 emit,value: {'age': '25', 'name': 'codeio'}
sin6 emit,value: 1 text
sin6 overload emit,value: text

信号槽N对N连接、断开连接

[python]   view plain  copy
  1. from PyQt5.QtWidgets import *  
  2. from PyQt5.QtCore import *  
  3.   
  4. class SinClass(QObject):  
  5.   
  6.     ##声明一个无参数的信号  
  7.     sin1 = pyqtSignal()  
  8.   
  9.     ##声明带一个int类型参数的信号  
  10.     sin2 = pyqtSignal(int)  
  11.   
  12.     def __init__(self,parent=None):  
  13.         super(SinClass,self).__init__(parent)  
  14.   
  15.         ##信号sin1连接到sin1Call和sin2Call这两个槽  
  16.         self.sin1.connect(self.sin1Call)  
  17.         self.sin1.connect(self.sin2Call)  
  18.   
  19.         ##信号sin2连接到信号sin1  
  20.         self.sin2.connect(self.sin1)  
  21.   
  22.         ##信号发射  
  23.         self.sin1.emit()  
  24.         self.sin2.emit(1)  
  25.   
  26.         ##断开sin1、sin2信号与各槽的连接  
  27.         self.sin1.disconnect(self.sin1Call)  
  28.         self.sin1.disconnect(self.sin2Call)  
  29.         self.sin2.disconnect(self.sin1)  
  30.   
  31.         ##信号sin1和sin2连接同一个槽sin1Call  
  32.         self.sin1.connect(self.sin1Call)  
  33.         self.sin2.connect(self.sin1Call)  
  34.   
  35.         ##信号再次发射  
  36.         self.sin1.emit()  
  37.         self.sin2.emit(1)  
  38.   
  39.     def sin1Call(self):  
  40.         print("sin1 emit")  
  41.   
  42.     def sin2Call(self):  
  43.         print("sin2 emit")  
  44.   
  45. sin = SinClass()  
运行结果:
sin1 emit
sin2 emit
sin1 emit
sin2 emit
sin1 emit
sin1 emit

多线程信号槽通信

[python]   view plain  copy
  1. from PyQt5.QtWidgets import *  
  2. from PyQt5.QtCore import *  
  3.   
  4. class Main(QWidget):  
  5.     def __init__(self, parent = None):  
  6.         super(Main,self).__init__(parent)  
  7.   
  8.         ##创建一个线程实例并设置名称、变量、信号槽  
  9.         self.thread = MyThread()  
  10.         self.thread.setIdentity("thread1")  
  11.         self.thread.sinOut.connect(self.outText)  
  12.         self.thread.setVal(6)  
  13.   
  14.     def outText(self,text):  
  15.         print(text)  
  16.   
  17. class MyThread(QThread):  
  18.   
  19.     sinOut = pyqtSignal(str)  
  20.   
  21.     def __init__(self,parent=None):  
  22.         super(MyThread,self).__init__(parent)  
  23.   
  24.         self.identity = None  
  25.   
  26.     def setIdentity(self,text):  
  27.         self.identity = text  
  28.   
  29.     def setVal(self,val):  
  30.         self.times = int(val)  
  31.   
  32.         ##执行线程的run方法  
  33.         self.start()  
  34.   
  35.     def run(self):  
  36.         while self.times > 0 and self.identity:  
  37.             ##发射信号  
  38.             self.sinOut.emit(self.identity+" "+str(self.times))  
  39.             self.times -= 1  
  40.   
  41. app = QApplication([])  
  42.   
  43. main = Main()  
  44. main.show()  
  45.   
  46. app.exec_()  
运行结果:
thread1 6
thread1 5
thread1 4
thread1 3
thread1 2
thread1 1

        信号(singal)与槽(slot)用于对象相互通信,信号:当某个对象的某个事件发生时,触发一个信号,槽:响应指定信号的所做的反应,其实信号槽类似于.NET里面的委托、事件,比如Repeater控件类,当行数据绑定后,触发一个ItemDataBound事件,不管使用者使用会监听该事件并做额外处理,其控件类内部都会触发该事件,这种机制很多程度提高了类的封装性和完整性。
  PyQt的窗体控件类已经有很多的内置信号,开发者也可以添加自己的自定义信号,信号槽有如下特点:
    - 一个信号可以连接到许多插槽。
    - 一个信号也可以连接到另一个信号。
    - 信号参数可以是任何Python类型。
    - 一个插槽可以连接到许多信号。
    - 连接可能会直接(即同步)或排队(即异步)。
    - 连接可能会跨线程。
    - 信号可能会断开

  (以上几条特点翻译于官方文档),接下来,我将以若干个实例,来体现以上几个特点。

内置信号槽的使用

[python]   view plain  copy
  1. from PyQt5.QtWidgets import *  
  2. from PyQt5.QtCore import *  
  3.     
  4. def sinTest():  
  5.     btn.setText("按钮文本改变")  
  6.     
  7. app = QApplication([])  
  8.     
  9. main = QWidget()  
  10. main.resize(200,100)  
  11. btn = QPushButton("按钮文本",main)  
  12. ##按钮btn的内置信号连接名为sinTest的槽  
  13. btn.clicked.connect(sinTest)  
  14. main.show()  
  15.     
  16. app.exec_()  

自定义信号槽的使用

[python]   view plain  copy
  1. class SinClass(QObject):  
  2.         
  3.     ##声明一个无参数的信号  
  4.     sin1 = pyqtSignal()  
  5.         
  6.     ##声明带一个int类型参数的信号  
  7.     sin2 = pyqtSignal(int)  
  8.         
  9.     ##声明带一个int和str类型参数的信号  
  10.     sin3 = pyqtSignal(int,str)  
  11.     
  12.     ##声明带一个列表类型参数的信号  
  13.     sin4 = pyqtSignal(list)  
  14.     
  15.     ##声明带一个字典类型参数的信号  
  16.     sin5 = pyqtSignal(dict)  
  17.     
  18.     ##声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号  
  19.     sin6 = pyqtSignal([int,str], [str])  
  20.         
  21.     def __init__(self,parent=None):  
  22.         super(SinClass,self).__init__(parent)  
  23.     
  24.         ##信号连接到指定槽  
  25.         self.sin1.connect(self.sin1Call)  
  26.         self.sin2.connect(self.sin2Call)  
  27.         self.sin3.connect(self.sin3Call)  
  28.         self.sin4.connect(self.sin4Call)  
  29.         self.sin5.connect(self.sin5Call)  
  30.         self.sin6[int,str].connect(self.sin6Call)  
  31.         self.sin6[str].connect(self.sin6OverLoad)  
  32.     
  33.         ##信号发射  
  34.         self.sin1.emit()  
  35.         self.sin2.emit(1)  
  36.         self.sin3.emit(1,"text")  
  37.         self.sin4.emit([1,2,3,4])  
  38.         self.sin5.emit({"name":"codeio","age":"25"})  
  39.         self.sin6[int,str].emit(1,"text")  
  40.         self.sin6[str].emit("text")  
  41.             
  42.     def sin1Call(self):  
  43.         print("sin1 emit")  
  44.     
  45.     def sin2Call(self,val):  
  46.         print("sin2 emit,value:",val)  
  47.     
  48.     def sin3Call(self,val,text):  
  49.         print("sin3 emit,value:",val,text)  
  50.     
  51.     def sin4Call(self,val):  
  52.         print("sin4 emit,value:",val)  
  53.             
  54.     def sin5Call(self,val):  
  55.         print("sin5 emit,value:",val)  
  56.     
  57.     def sin6Call(self,val,text):  
  58.         print("sin6 emit,value:",val,text)  
  59.     
  60.     def sin6OverLoad(self,val):  
  61.         print("sin6 overload emit,value:",val)  
  62.     
  63. sin = SinClass()  
运行结果:
sin1 emit
sin2 emit,value: 1
sin3 emit,value: 1 text
sin4 emit,value: [1, 2, 3, 4]
sin5 emit,value: {'age': '25', 'name': 'codeio'}
sin6 emit,value: 1 text
sin6 overload emit,value: text

信号槽N对N连接、断开连接

[python]   view plain  copy
  1. from PyQt5.QtWidgets import *  
  2. from PyQt5.QtCore import *  
  3.   
  4. class SinClass(QObject):  
  5.   
  6.     ##声明一个无参数的信号  
  7.     sin1 = pyqtSignal()  
  8.   
  9.     ##声明带一个int类型参数的信号  
  10.     sin2 = pyqtSignal(int)  
  11.   
  12.     def __init__(self,parent=None):  
  13.         super(SinClass,self).__init__(parent)  
  14.   
  15.         ##信号sin1连接到sin1Call和sin2Call这两个槽  
  16.         self.sin1.connect(self.sin1Call)  
  17.         self.sin1.connect(self.sin2Call)  
  18.   
  19.         ##信号sin2连接到信号sin1  
  20.         self.sin2.connect(self.sin1)  
  21.   
  22.         ##信号发射  
  23.         self.sin1.emit()  
  24.         self.sin2.emit(1)  
  25.   
  26.         ##断开sin1、sin2信号与各槽的连接  
  27.         self.sin1.disconnect(self.sin1Call)  
  28.         self.sin1.disconnect(self.sin2Call)  
  29.         self.sin2.disconnect(self.sin1)  
  30.   
  31.         ##信号sin1和sin2连接同一个槽sin1Call  
  32.         self.sin1.connect(self.sin1Call)  
  33.         self.sin2.connect(self.sin1Call)  
  34.   
  35.         ##信号再次发射  
  36.         self.sin1.emit()  
  37.         self.sin2.emit(1)  
  38.   
  39.     def sin1Call(self):  
  40.         print("sin1 emit")  
  41.   
  42.     def sin2Call(self):  
  43.         print("sin2 emit")  
  44.   
  45. sin = SinClass()  
运行结果:
sin1 emit
sin2 emit
sin1 emit
sin2 emit
sin1 emit
sin1 emit

多线程信号槽通信

[python]   view plain  copy
  1. from PyQt5.QtWidgets import *  
  2. from PyQt5.QtCore import *  
  3.   
  4. class Main(QWidget):  
  5.     def __init__(self, parent = None):  
  6.         super(Main,self).__init__(parent)  
  7.   
  8.         ##创建一个线程实例并设置名称、变量、信号槽  
  9.         self.thread = MyThread()  
  10.         self.thread.setIdentity("thread1")  
  11.         self.thread.sinOut.connect(self.outText)  
  12.         self.thread.setVal(6)  
  13.   
  14.     def outText(self,text):  
  15.         print(text)  
  16.   
  17. class MyThread(QThread):  
  18.   
  19.     sinOut = pyqtSignal(str)  
  20.   
  21.     def __init__(self,parent=None):  
  22.         super(MyThread,self).__init__(parent)  
  23.   
  24.         self.identity = None  
  25.   
  26.     def setIdentity(self,text):  
  27.         self.identity = text  
  28.   
  29.     def setVal(self,val):  
  30.         self.times = int(val)  
  31.   
  32.         ##执行线程的run方法  
  33.         self.start()  
  34.   
  35.     def run(self):  
  36.         while self.times > 0 and self.identity:  
  37.             ##发射信号  
  38.             self.sinOut.emit(self.identity+" "+str(self.times))  
  39.             self.times -= 1  
  40.   
  41. app = QApplication([])  
  42.   
  43. main = Main()  
  44. main.show()  
  45.   
  46. app.exec_()  
运行结果:
thread1 6
thread1 5
thread1 4
thread1 3
thread1 2
thread1 1

猜你喜欢

转载自blog.csdn.net/qq61394323/article/details/69951760
今日推荐