PyQt5学习笔记13----pyqt线程间通信
生活随笔
收集整理的這篇文章主要介紹了
PyQt5学习笔记13----pyqt线程间通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?信號(singal)與槽(slot)用于對象相互通信,信號:當某個對象的某個事件發生時,觸發一個信號,槽:響應指定信號的所做的反應,其實信號槽類似于.NET里面的委托、事件,比如Repeater控件類,當行數據綁定后,觸發一個ItemDataBound事件,不管使用者使用會監聽該事件并做額外處理,其控件類內部都會觸發該事件,這種機制很多程度提高了類的封裝性和完整性。
PyQt的窗體控件類已經有很多的內置信號,開發者也可以添加自己的自定義信號,信號槽有如下特點:
- 一個信號可以連接到許多插槽。
- 一個信號也可以連接到另一個信號。
- 信號參數可以是任何Python類型。
- 一個插槽可以連接到許多信號。
- 連接可能會直接(即同步)或排隊(即異步)。
- 連接可能會跨線程。
- 信號可能會斷開
from?PyQt5.QtWidgets?import?*?? from?PyQt5.QtCore?import?*?? ???? def?sinTest():?? ????btn.setText("按鈕文本改變")?? ???? app?=?QApplication([])?? ???? main?=?QWidget()?? main.resize(200,100)?? btn?=?QPushButton("按鈕文本",main)?? ##按鈕btn的內置信號連接名為sinTest的槽?? btn.clicked.connect(sinTest)?? main.show()?? ???? app.exec_()??
class?SinClass(QObject):?? ???????? ????##聲明一個無參數的信號?? ????sin1?=?pyqtSignal()?? ???????? ????##聲明帶一個int類型參數的信號?? ????sin2?=?pyqtSignal(int)?? ???????? ????##聲明帶一個int和str類型參數的信號?? ????sin3?=?pyqtSignal(int,str)?? ???? ????##聲明帶一個列表類型參數的信號?? ????sin4?=?pyqtSignal(list)?? ???? ????##聲明帶一個字典類型參數的信號?? ????sin5?=?pyqtSignal(dict)?? ???? ????##聲明一個多重載版本的信號,包括了一個帶int和str類型參數的信號,以及帶str參數的信號?? ????sin6?=?pyqtSignal([int,str],?[str])?? ???????? ????def?__init__(self,parent=None):?? ????????super(SinClass,self).__init__(parent)?? ???? ????????##信號連接到指定槽?? ????????self.sin1.connect(self.sin1Call)?? ????????self.sin2.connect(self.sin2Call)?? ????????self.sin3.connect(self.sin3Call)?? ????????self.sin4.connect(self.sin4Call)?? ????????self.sin5.connect(self.sin5Call)?? ????????self.sin6[int,str].connect(self.sin6Call)?? ????????self.sin6[str].connect(self.sin6OverLoad)?? ???? ????????##信號發射?? ????????self.sin1.emit()?? ????????self.sin2.emit(1)?? ????????self.sin3.emit(1,"text")?? ????????self.sin4.emit([1,2,3,4])?? ????????self.sin5.emit({"name":"codeio","age":"25"})?? ????????self.sin6[int,str].emit(1,"text")?? ????????self.sin6[str].emit("text")?? ???????????? ????def?sin1Call(self):?? ????????print("sin1?emit")?? ???? ????def?sin2Call(self,val):?? ????????print("sin2?emit,value:",val)?? ???? ????def?sin3Call(self,val,text):?? ????????print("sin3?emit,value:",val,text)?? ???? ????def?sin4Call(self,val):?? ????????print("sin4?emit,value:",val)?? ???????????? ????def?sin5Call(self,val):?? ????????print("sin5?emit,value:",val)?? ???? ????def?sin6Call(self,val,text):?? ????????print("sin6?emit,value:",val,text)?? ???? ????def?sin6OverLoad(self,val):?? ????????print("sin6?overload?emit,value:",val)?? ???? 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
from?PyQt5.QtWidgets?import?*?? from?PyQt5.QtCore?import?*?? ?? class?SinClass(QObject):?? ?? ????##聲明一個無參數的信號?? ????sin1?=?pyqtSignal()?? ?? ????##聲明帶一個int類型參數的信號?? ????sin2?=?pyqtSignal(int)?? ?? ????def?__init__(self,parent=None):?? ????????super(SinClass,self).__init__(parent)?? ?? ????????##信號sin1連接到sin1Call和sin2Call這兩個槽?? ????????self.sin1.connect(self.sin1Call)?? ????????self.sin1.connect(self.sin2Call)?? ?? ????????##信號sin2連接到信號sin1?? ????????self.sin2.connect(self.sin1)?? ?? ????????##信號發射?? ????????self.sin1.emit()?? ????????self.sin2.emit(1)?? ?? ????????##斷開sin1、sin2信號與各槽的連接?? ????????self.sin1.disconnect(self.sin1Call)?? ????????self.sin1.disconnect(self.sin2Call)?? ????????self.sin2.disconnect(self.sin1)?? ?? ????????##信號sin1和sin2連接同一個槽sin1Call?? ????????self.sin1.connect(self.sin1Call)?? ????????self.sin2.connect(self.sin1Call)?? ?? ????????##信號再次發射?? ????????self.sin1.emit()?? ????????self.sin2.emit(1)?? ?? ????def?sin1Call(self):?? ????????print("sin1?emit")?? ?? ????def?sin2Call(self):?? ????????print("sin2?emit")?? ?? sin?=?SinClass()??
運行結果:
sin1 emit
sin2 emit
sin1 emit
sin2 emit
sin1 emit
sin1 emit
from?PyQt5.QtWidgets?import?*?? from?PyQt5.QtCore?import?*?? ?? class?Main(QWidget):?? ????def?__init__(self,?parent?=?None):?? ????????super(Main,self).__init__(parent)?? ?? ????????##創建一個線程實例并設置名稱、變量、信號槽?? ????????self.thread?=?MyThread()?? ????????self.thread.setIdentity("thread1")?? ????????self.thread.sinOut.connect(self.outText)?? ????????self.thread.setVal(6)?? ?? ????def?outText(self,text):?? ????????print(text)?? ?? class?MyThread(QThread):?? ?? ????sinOut?=?pyqtSignal(str)?? ?? ????def?__init__(self,parent=None):?? ????????super(MyThread,self).__init__(parent)?? ?? ????????self.identity?=?None?? ?? ????def?setIdentity(self,text):?? ????????self.identity?=?text?? ?? ????def?setVal(self,val):?? ????????self.times?=?int(val)?? ?? ????????##執行線程的run方法?? ????????self.start()?? ?? ????def?run(self):?? ????????while?self.times?>?0?and?self.identity:?? ????????????##發射信號?? ????????????self.sinOut.emit(self.identity+"?"+str(self.times))?? ????????????self.times?-=?1?? ?? app?=?QApplication([])?? ?? main?=?Main()?? main.show()?? ?? app.exec_()?? 運行結果:
thread1 6
thread1 5
thread1 4
thread1 3
thread1 2
thread1 1
PyQt的窗體控件類已經有很多的內置信號,開發者也可以添加自己的自定義信號,信號槽有如下特點:
- 一個信號可以連接到許多插槽。
- 一個信號也可以連接到另一個信號。
- 信號參數可以是任何Python類型。
- 一個插槽可以連接到許多信號。
- 連接可能會直接(即同步)或排隊(即異步)。
- 連接可能會跨線程。
- 信號可能會斷開
(以上幾條特點翻譯于官方文檔),接下來,我將以若干個實例,來體現以上幾個特點。
內置信號槽的使用
[python]?view plaincopy
自定義信號槽的使用
[python]?view plaincopysin1 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 plaincopy
sin1 emit
sin2 emit
sin1 emit
sin2 emit
sin1 emit
sin1 emit
多線程信號槽通信
[python]?view plaincopythread1 6
thread1 5
thread1 4
thread1 3
thread1 2
thread1 1
總結
以上是生活随笔為你收集整理的PyQt5学习笔记13----pyqt线程间通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在32位程序中突破地址空间限制使用超
- 下一篇: JavaScript学习笔记之 数组方