您的位置:首页 > 编程语言 > Qt开发

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

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

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

内置信号槽的使用

[python] view
plain copy

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



自定义信号槽的使用

[python] view
plain copy

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

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

[python] view
plain copy

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

多线程信号槽通信

[python] view
plain copy

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: