PyQt5学习笔记13----pyqt线程间通信

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

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

内置信号槽的使用

 

 
  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_()

自定义信号槽的使用

 
  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连接、断开连接

 

 
  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
 

多线程信号槽通信

 
  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

--------------------- 本文来自 翻滚吧挨踢男 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/a359680405/article/details/45196207?utm_source=copy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值