訊號和槽的機制
一.介紹
GUI應用程式是事件驅動的。 事件主要由應用程式的使用者生成。 但它們也可以通過其他手段產生,例如:網路連線,視窗
管理器或定時器。 當我們呼叫應用程式的exec_()方法時,應用程式進入主迴圈。 主迴圈獲取事件並將其傳送到物件。
在事件模型中,有三個參與者:
- 事件來源
- 事件物件
- 事件目標
事件源是其狀態更改的物件。 它會生成事件。 事件物件(event)將狀態更改封裝在事件源中。 事件目標是要通知的物件。
事件源物件將處理事件的任務委託給事件目標。
PyQt5具有獨特的訊號和插槽機制來處理事件。 訊號和槽用於物件之間的通訊。 發生特定事件時發出訊號。 槽可以是任何
Python可呼叫的函式。 當發射連線的訊號時會呼叫一個槽。
接下來介紹幾種訊號與槽的對應關係
二.一個訊號對應一個槽
1 import sys 2 from PyQt5.QtWidgets import QApplication, QWidget, QPushButton 3 4 5 class Demo(QWidget): 6 def __init__(self): 7 super(Demo, self).__init__() 8 self.button = QPushButton('Start', self) 9 self.button.clicked.connect(self.change_text)10 11 def change_text(self): 12 print('change text') 13 14 15 if __name__ == '__main__': 16 app = QApplication(sys.argv) 17 demo = Demo() 18 demo.show() 19 sys.exit(app.exec_())
1. 類Demo繼承QWidget,可以將QWidget看作是一種毛坯房,還沒有裝修,而我們往其中放入QPushButton、QLabel等控制元件就
相當於在裝修這間毛坯房。類似的毛坯房還有QMainWindow和QDialog等
2.連線訊號與槽函式。self.button就是一個控制元件,clicked(按鈕被點選)是該控制元件的一個訊號,connect()即連線,self.change_text即
下方定義的函式(我們稱之為槽函式)。所以通用的公式可以是:widget.signal.connect(slot);當然也可以解綁,即改為disconnect
3.當按鍵按下時,控制檯輸出字串
三.多個訊號連線一個槽
import sys from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton) class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(200, 200, 300, 300) bt1 = QPushButton('bt1',self) bt1.setGeometry(30,180,50,50) bt2 = QPushButton('bt2',self) bt2.setGeometry(100,180,50,50) bt3 = QPushButton('bt3',self) bt3.setGeometry(170,180,50,50) bt1.clicked.connect(self.buttonclicked) bt2.clicked.connect(self.buttonclicked) bt3.clicked.connect(self.buttonclicked) self.show() def buttonclicked(self): sender = self.sender() if sender.text() == 'bt1': print('bt1') elif sender.text() == 'bt2': print('bt2') elif sender.text() == 'bt3': print('bt3') if __name__ == '__main__': app = QApplication(sys.argv) demo = Example() sys.exit(app.exec_())
通過呼叫sender()方法來確定我們點選了哪個按鈕,判斷出後進行相應操作
四.自定義訊號
1 import sys 2 from PyQt5.QtCore import pyqtSignal 3 from PyQt5.QtWidgets import QApplication, QWidget, QLabel 4 5 6 class Demo(QWidget): 7 my_signal = pyqtSignal() 8 9 def __init__(self): 10 super(Demo, self).__init__() 11 self.label = QLabel('Hello World', self) 12 self.my_signal.connect(self.change_text) 13 14 def change_text(self): 15 if self.label.text() == 'Hello World': 16 self.label.setText('Hello PyQt5') 17 else: 18 self.label.setText('Hello World') 19 20 def mousePressEvent(self, QMouseEvent): 21 self.my_signal.emit() 22 23 24 if __name__ == '__main__': 25 app = QApplication(sys.argv) 26 demo = Demo() 27 demo.show() 28 sys.exit(app.exec_())
1. 需要先匯入pyqtSignal;
2. 例項化一個自定義的訊號;
3. 將自定義的訊號連線到自定義的槽函式上;
4. mousePressEvent()方法是許多控制元件自帶的,這裡來自於QWidget。該方法用來監測滑鼠是否有按下。現在滑鼠若被按下,則會發出自定義的訊號。