1. 程式人生 > 其它 >PyQt5入門(二十)訊號與槽(上)

PyQt5入門(二十)訊號與槽(上)

技術標籤:PyQt5pyqt5訊號與槽基礎自定義訊號實現訊號與槽的通訊可以傳遞多個引數的訊號為類新增多個訊號(過載形式)訊號與槽N對N連線與斷開連線

一.訊號與槽基礎

前面已經用過很多,下面簡單舉個例子回顧一下。

程式碼:

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.initUI()
    def initUI(self):
        self.setGeometry(300,300,300,100)
        self.setWindowTitle('訊號(Signal)與槽(Slot)')
        self.btn=QPushButton('我的按鈕',self)
        self.btn.clicked.connect(self.onClick)
    def onClick(self):
        self.btn.setText('訊號已經發出')
        self.btn.setStyleSheet('QPushButton(max-width:200px;min-width:200px)')


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=Demo()
    main.show()
    sys.exit(app.exec_())

執行結果:

二.自定義訊號實現物件之間的通訊

程式碼:

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class MyTypeSignal(QObject):
    #定義一個訊號
    sendmsg=pyqtSignal(object)
    #呼叫run來實現觸發
    def run(self):
        self.sendmsg.emit('Hello PyQt5')#給槽傳遞一個引數


class MySlot(QObject):
    #槽函式
    def get(self,msg):
        print('資訊:'+msg)


if __name__=='__main__':
    send=MyTypeSignal()
    slot=MySlot()
    send.sendmsg.connect(slot.get)#連線訊號與槽函式
    send.run()#傳送訊號
    #斷開訊號與槽的連線
    #send.sendmsg.disconnect(slot.get)


執行結果:

三.可以傳遞多個引數的訊號

程式碼:

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class MyTypeSignal(QObject):
    #定義一個訊號
    sendmsg=pyqtSignal(object)
    #傳送三個引數的訊號
    sendmsg1=pyqtSignal(str,int,int)
    #呼叫run來實現觸發
    def run(self):
        self.sendmsg.emit('Hello PyQt5')#給槽傳遞一個引數

    def run1(self):
        self.sendmsg1.emit('hello',3,4)


class MySlot(QObject):
    #槽函式
    def get(self,msg):
        print('資訊:'+msg)
    def get1(self,msg,a,b):
        print(msg)
        print(a+b)


if __name__=='__main__':
    send=MyTypeSignal()
    slot=MySlot()

    send.sendmsg.connect(slot.get)#連線訊號與槽函式
    send.sendmsg1.connect(slot.get1)

    send.run()#傳送訊號
    send.run1()#別忘了呼叫相應的觸發函式!!!!

    #斷開訊號與槽的連線
    #send.sendmsg.disconnect(slot.get)


執行結果:

四.為類新增多個訊號(過載形式的訊號)

程式碼:

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class MultiSignal(QObject):
    #無引數
    signal1=pyqtSignal()
    #有一個整型的引數
    signal2 = pyqtSignal(int)
    #引數一是整型,引數二是字元型
    signal3 = pyqtSignal(int,str)
    #引數是一個列表
    signal4 = pyqtSignal(list)
    # 引數是一個字典
    signal5 = pyqtSignal(dict)
    #宣告一個過載版本的訊號,中括號之間是或的意思,也就是槽函式可以是兩個引數:int和str型別,也可以是一個引數:str型別
    signal6 = pyqtSignal([int,str],[str])

    def __init__(self):
        super(MultiSignal, self).__init__()
        self.signal1.connect(self.signalcall1)
        self.signal2.connect(self.signalcall2)
        self.signal3.connect(self.signalcall3)
        self.signal4.connect(self.signalcall4)
        self.signal5.connect(self.signalcall5)
        #self.signal6.connect(self.signalcall6)#預設關聯到重構的第一個槽函式上
        # 為了可讀性,可像下面那樣寫
        self.signal6[str].connect(self.signalcall6Overload)
        self.signal6[int, str].connect(self.signalcall6)

        self.signal1.emit()
        self.signal2.emit(10)
        self.signal3.emit(1,'hello world')
        self.signal4.emit([1,2,3,4,5])
        self.signal5.emit({'name':'Bill','age':30})
        self.signal6[str].emit('test')
        self.signal6[int, str].emit(20,'mytest')



    #槽函式
    def signalcall1(self):
        print('signal1 emit')

    def signalcall2(self,val):
        print('signa2 emit,value:',val)

    def signalcall3(self,val,text):
        print('signa3 emit,value:',val,text)

    def signalcall4(self,val):
        print('signa4 emit,value:',val)

    def signalcall5(self,val):
        print('signa5 emit,value:',val)

    def signalcall6(self,val,text):
        print('signa6 emit,value:',val,text)

    def signalcall6Overload(self,val):
        print('signa6 overload emit,value:',val)


if __name__=='__main__':
    multiSignal=MultiSignal()

執行結果:

五.訊號與槽的N對N連線與斷開連線

程式碼:

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class NNSignal(QObject):
    signal1=pyqtSignal()#無引數
    signal2=pyqtSignal(int)
    signal3=pyqtSignal()

    def __init__(self):
        super(NNSignal, self).__init__()
        #一個訊號對應多個槽
        self.signal1.connect(self.call1)
        self.signal1.connect(self.call11)

        self.signal1.emit()
        #訊號繫結到訊號上
        self.signal2.connect(self.signal1)
        print('*****************************')
        self.signal2.emit(2)#觸發了訊號1
        '''
        以上操作的執行結果
        call1 emit
        call11 emit
        call1 emit
        call11 emit
        '''
        print('************************************')
        #解綁
        self.signal1.disconnect(self.call1)
        self.signal1.disconnect(self.call11)
        self.signal2.disconnect(self.signal1)
        #重新繫結
        self.signal1.connect(self.call1)
        self.signal2.connect(self.call2)
        #一個槽函式繫結到多個訊號上
        self.signal3.connect(self.call1)

        self.signal1.emit()
        self.signal2.emit(100)
        self.signal3.emit()

    def call1(self):
        print('call1 emit')

    def call11(self):
        print('call11 emit')

    def call2(self,val):
        print('call2 emit',val)


if __name__=='__main__':
    nnSignal=NNSignal()

執行結果:

call1 emit
call11 emit
*****************************
call1 emit
call11 emit
************************************
call1 emit
call2 emit 100
call1 emit