掌握Signal&Slot就能掌握全世界
Qt的特色眾所皆知,那便是Signal及Slot。如果沒有這項機制,一般來說在實作上會使用callback function的方式將行為塞入對應的UI操作,例如urwid等傳統的UI套件便是這樣設計。
建立Signal & Slot
事實上,實作Signal&Slot並不困難,尤其在python中PySide2提供了相對應的decorator供開發者使用,在實作上更加的方便。
而實作上其實有許多種方式,這邊筆者將提供筆者自己常用的方法。
建立Slot
首先我們要來建立一個Slot method,這步驟我們要先import Qt核心。
from PySide2 import QtCore
宣告一個method並加入Slot decorator,這邊我們繼續使用上一篇的例子,在MainWindow中新增離開的method。
@QtCore.Slot()
def exit(self):
self.close()
完成!沒錯,建立Slot就是這麼簡單。
連結Slot
接下來我們要連結Slot到我們所建立的UI元件,這邊我要將 exit()
方法連結到sleeping的按鈕上。
def build_h_layout(self):
hello_btn = QPushButton('Hello')
work_btn = QPushButton('Working')
play_btn = QPushButton('Playing')
sleep_btn = QPushButton('Sleeping')
h_layout = QHBoxLayout()
h_layout.addWidget(hello_btn)
h_layout.addWidget(work_btn)
h_layout.addWidget(play_btn)
h_layout.addWidget(sleep_btn)
# Here is the SIGNAL connection
sleep_btn.clicked.connect(self.exit)
return h_layout
Python中連結Slot的方式與C++有些許不同,須先將Signal的名稱列出,並使用 connect()
來連結Slot。
這樣便完成了! 非常簡單!
自定義Signal
事實上我們不一定只用上述UI觸發的被動式Signal,我們也希望可以自己建立Signal並在想要使用的時候主動觸發,即Qt中的 emit()
方法。
建立Signal
from PySide2.QtCore import Signal
宣告Signal,使用 Siganl()
宣告並且決定輸入的參數類型,或是無輸入參數
class MainWindow(QMainWindow):
hello_signal = Signal(str)
這邊我的signal將會傳送一個字串給Slot,而Slot也應該有相對應的接收類別。
@QtCore.Slot(str)
def say_hello(self, msg):
print('Hello ' + msg)
最後就是串接Signal 及 Slot了,並且觸發他!
self.hello_signal.connect(self.say_hello)
self.hello_signal.emit('Pyside2!')
Result
Source Code
完整代碼請看: Signal / Slot
結論
Signal & Slot是Qt的核心功能之一,在物件之間傳遞資訊以及互動式介面的實作上非常的重要,而比起C++在Python的環境下這個功能可以更加的活用,因為我們甚至可以以非常簡單的方式就讓信號槽為我們傳遞各種不同的資料結構,包括dict,list,甚至是我們的物件。
Pyside2系列教程下一篇: