[Python自學] PyQT5-信號與槽


一、簡單Demo

簡單使用信號和槽(之前常用的使用方式):

class DemoWin(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.resize(400, 250)
        self.btn = QPushButton("發送信號", self)
        # 發送一個clicked信號,綁定槽函數是self.onClick()
        self.btn.clicked.connect(self.onClick)

        # 添加窗口標題
        self.setWindowTitle("SignalDemo")

    # 槽函數,接收btn的clicked信號
    def onClick(self):
        self.btn.setText("接收到信號")
        self.btn.setStyleSheet("max-width:200px;min-width:200px;")

這是最簡單的信號和槽的使用方法,其中clicked事件是button的默認事件,我們將其綁定到自定義的onClick槽函數即可。

二、自定義信號Demo

# 導入信號
from PyQt5.QtCore import Qt, QObject, pyqtSignal


# 自定義信號類
class MySignal(QObject):
    sendmsg = pyqtSignal(object)  # 定義一個信號,object表示傳遞一個參數(object是python中的基類)

    def run(self):
        self.sendmsg.emit("Hello PyQt5")  # 觸發信號,並傳遞一個string參數


class MySlot(QObject):
    # 定義槽函數,接收一個string參數
    def slot(self, msg):
        print("接收到的信息是:", msg)


if __name__ == '__main__':
    mySignal = MySignal()
    mySlot = MySlot()
    # 將信號和槽進行綁定
    mySignal.sendmsg.connect(mySlot.slot)
    #mySignal.sendmsg.disconnect(mySlot.slot)  # 斷開連接
# 觸發信號 mySignal.run() # 打印 "接收到的信息是: Hello PyQt5"

1)首先創建一個pyqtSignal信號實例(參數對應槽的參數的類型)

2)使用connect綁定信號和槽(使用后可以手工斷開連接,使用mySignal.sendmsg.disconnect(mySlot.slot))

3)觸發信號

三、信號傳遞數據(多個參數)

# 導入信號
from PyQt5.QtCore import Qt, QObject, pyqtSignal


# 自定義信號類
class MySignal(QObject):
    sendmsg = pyqtSignal(object, int, dict)  # 定義一個信號,傳遞三個參數

    def run(self):
        self.sendmsg.emit("Hello PyQt5", 50, {"name": "leo"})  # 觸發信號,並傳遞三個參數,參數類型在信號定義時指定


class MySlot(QObject):
    # 定義槽函數,接收一個string參數
    def slot(self, msg,age,name):
        print("接收到的信息是:", msg)
        print("接收到的年齡是:", age)
        print("接收到的名稱是:", name['name'])


if __name__ == '__main__':
    mySignal = MySignal()
    mySlot = MySlot()
    # 將信號和槽進行綁定
    mySignal.sendmsg.connect(mySlot.slot)
    # 觸發信號
    mySignal.run()  # 打印 "接收到的信息是: Hello PyQt5"

可以看到,我們在定義信號的時候指定了對應槽函數的參數類型,並在觸發信號時傳入實際的參數,這樣槽函數就可以接受到數據了。

四、多對多綁定,綁定信號

信號和槽是可以N對N綁定的,也就是說在參數一致的情況下,一個信號可以綁定多個槽函數,一個槽函數也可以綁定多個信號。

信號還可以與信號綁定,例如B信號綁定了A信號,A信號和A槽函數綁定,則觸發B最終觸發A槽函數。

Demo:

# 導入信號
from PyQt5.QtCore import Qt, QObject, pyqtSignal


# 自定義信號類
class MySignal(QObject):
    signal1 = pyqtSignal(object)
    signal2 = pyqtSignal(object,object)

    def __init__(self):
        super(MySignal, self).__init__()

        # signal1綁定多個槽函數(slot1和slot2)
        self.signal1.connect(self.slot1)
        self.signal1.connect(self.slot2)

        # signal2綁定signal1
        self.signal2.connect(self.signal1)

        self.signal1.emit(1)  # 觸發slot1和slot2
        self.signal2.emit(2,3)  # 雖然目前signal2和signal1綁定,但是signal2.emit的參數還是必須和signal定義時一致

    def slot1(self, num):
        print("slot1 " + str(num))

    def slot2(self, num):
        print("slot2 " + str(num))


if __name__ == '__main__':
    mySignal = MySignal()

特別注意,signal2和signal1綁定后,槽函數的參數應該是signal1一致,而signal2.emit的參數應該是signal2定義時的參數類型一致。

signal2和signal1綁定時,觸發signal2的參數個數要多余signal1。例如signal1有一個int參數,那么singal2的第一個參數也必須是int,后面多的參數沒用。

上述代碼的輸出結果:

slot1 1
slot2 1
slot1 2  # 這里的2就是signal2傳遞給signal1的第一個參數,然后signal1將其傳遞給了slot1
slot2 2

 

==

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM