一、介紹
訊號(Signal
)和槽(Slot
)是Qt中的核心機制,也是PyQt
變成中物件之間進行通訊的機制
在pyqt5
中,每一個QObject
物件和pyqt
中所有繼承自QWidget
的控制元件都支援訊號和槽
當訊號發射時,連線槽函式將會自動執行,pyqt5
中訊號與槽通過connect()
函式連線起來的。
在pyqt5
中訊號主要分兩類:
- 1.內建訊號(詳細參考各個元件)
- 2.自定義訊號(主要用於元件之間資料的傳遞與視窗互動)
二、內建訊號的簡單介紹
使用
connect()
方法將訊號與槽函式繫結在一起,使用disconnect()
函式將訊號與槽解除繫結
-
1、按鈕點選事件(舉例)
import sys from PyQt5.Qt import * class Window(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle(`按鈕事件`) self.resize(500, 500) self.move(400, 200) self.btn = QPushButton(`按鈕`, self) self.init_ui() def init_ui(self): self.btn.resize(100, 30) self.btn.move(100, 50) self.btn.clicked.connect(self.btn_hand) def btn_hand(self): print(`按鈕點選了`) if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_()) 複製程式碼
-
2、如果連線的事件要傳遞引數直接使用
lambda
函式... def init_ui(self): self.btn.resize(100, 30) self.btn.move(100, 50) self.btn.clicked.connect(lambda: self.btn_hand(1)) def btn_hand(self, flag): print(`按鈕點選了:{}`.format(flag)) ... 複製程式碼
三、自定義訊號
-
1、最基本無引數的訊號與槽
import sys from PyQt5.Qt import * class SignalObj(QObject): """ 定義一個訊號的類 """ # 自定義一個訊號 sendMsg = pyqtSignal() def __init__(self): super().__init__() def run(self): self.sendMsg.emit() class Window(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle(`自定義事件`) self.resize(500, 500) self.move(400, 200) self.btn = QPushButton(`按鈕`, self) self.send = SignalObj() # 將事件與槽建立關聯 self.send.sendMsg.connect(self.slot_hand) self.init_ui() def init_ui(self): # 系統中自帶的事件與槽函式建立連線 self.btn.clicked.connect(self.btn_hand) def btn_hand(self): self.send.run() @staticmethod def slot_hand(): print(`我是自定義的槽函式`) if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_()) 複製程式碼
-
2、訊號中發射出資料
import sys from PyQt5.Qt import * class SignalObj(QObject): """ 定義一個訊號的類 """ # 自定義一個訊號,注意這個地方定義約束髮送出去的引數型別,下面要一致 sendMsg = pyqtSignal(str) def __init__(self): super().__init__() def run(self): self.sendMsg.emit(`hello`) class Window(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle(`自定義事件`) self.resize(500, 500) self.move(400, 200) self.btn = QPushButton(`按鈕`, self) self.send = SignalObj() # 將事件與槽建立關聯 self.send.sendMsg.connect(self.slot_hand) self.init_ui() def init_ui(self): # 系統中自帶的事件與槽函式建立連線 self.btn.clicked.connect(self.btn_hand) def btn_hand(self): self.send.run() @staticmethod def slot_hand(msg): print(f`我是自定義的槽函式:{msg}`) if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_()) 複製程式碼
-
3、對於傳送多種不同資料型別的事件
import sys from PyQt5.Qt import * class SignalObj(QObject): """ 定義一個訊號的類 """ # 自定義一個訊號,注意這個地方定義約束髮送出去的引數型別,下面要一致 sendMsg = pyqtSignal([str], [int]) def __init__(self): super().__init__() def run(self): self.sendMsg[str].emit(`hello`) self.sendMsg[int].emit(999) class Window(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle(`自定義事件`) self.resize(500, 500) self.move(400, 200) self.btn = QPushButton(`按鈕`, self) self.send = SignalObj() # 將事件與槽建立關聯(這個地方你要接收那個資料型別的事件) self.send.sendMsg[int].connect(self.slot_hand) self.init_ui() def init_ui(self): # 系統中自帶的事件與槽函式建立連線 self.btn.clicked.connect(self.btn_hand) def btn_hand(self): self.send.run() @staticmethod def slot_hand(msg): print(f`我是自定義的槽函式:{msg}`) if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_()) 複製程式碼
四、使用裝飾器訊號與槽
-
1、使用格式
@PyQt5.QtCore.pyqtSlot(引數) def on_傳送者物件名稱_發射訊號名稱(self,引數): pass 複製程式碼
-
2、注意點,使用裝飾器必須定義兩個東西
QMetaObject.connectSlotsByName(self)
- 給需要繫結事件的定義一個
id
(self.btn.setObjectName(`名稱`)
)
-
3、按鈕的普通事件
... class Window(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle(`裝飾器訊號與槽`) self.resize(500, 500) self.move(400, 200) self.btn = QPushButton(`按鈕`, self) self.init_ui() def init_ui(self): self.btn.clicked.connect(self.btn_hand) @staticmethod def btn_hand(): print(`使用connect點選了按鈕`) ... 複製程式碼
-
4、使用裝飾器後的事件
... class Window(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle(`裝飾器訊號與槽`) self.resize(500, 500) self.move(400, 200) self.btn = QPushButton(`按鈕`, self) self.init_ui() # 要在載入元件後使用 QMetaObject.connectSlotsByName(self) def init_ui(self): # 這個地方定義的名字直接在下面使用 self.btn.setObjectName(`btn`) @pyqtSlot() def on_btn_clicked(self): print(`使用裝飾器點選了按鈕`) ... 複製程式碼