信號與槽機制是對事件機制的高級封裝
事件機制更偏向于底層

每個 Qt 應(yīng)用程序?qū)?yīng)一個 QAppliation 對象
一個應(yīng)用程序擁有幾個消息隊列,應(yīng)用程序的消息循環(huán),就是在處理這些隊列中的消息
用戶的操作會產(chǎn)生各種事件消息
消息首先會被操作系統(tǒng)接收,然后操作系統(tǒng)會把消息分發(fā)到對應(yīng)的各應(yīng)用程序的“消息隊列”中
比如分為兩個隊列:系統(tǒng)產(chǎn)生的消息組成的隊列(鼠標(biāo)事件、鍵盤事件、拖放事件),程序內(nèi)部產(chǎn)生的消息組成的隊列(定時器事件、繪屏事件)
消息循環(huán):
不斷地按順序檢測消息隊列中是否有消息
若發(fā)現(xiàn)“事件消息”,則包裝成“QEvent 對象”進(jìn)行分發(fā)處理
將事件接收者(receiver)和事件對象(evt)傳遞給 QApplication 對象的 notify(receiver, evt) 方法進(jìn)行處理
QApplication 對象是否安裝事件過濾器(事件過濾器可設(shè)置多個,但會按照設(shè)置的逆序進(jìn)行分發(fā))
- 是:QApplication 對象 n 個事件過濾器 eventFilter(watched, evt) 方法的返回值,若為 True 則不再繼續(xù)分發(fā)(告訴系統(tǒng)該事件已被處理)
- 否:分發(fā)給 receiver 對象的 event(evt) 方法,此方法會根據(jù) evt 的事件類型分發(fā)給 receiver 具體的事件函數(shù)
如 mousePressEvent(evt)、mouseReleaseEvent(evt)、mouseClickEvent(evt) 等
部分控件在這些具體的事件方法中,可能發(fā)射了對應(yīng)的信號(pressed、released、clicked 等)
import sys
form PyQt5.Qt import *
# 通過繼承重寫方法
class App(QApplication):
def notify(self, recv, evt):
if recv.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress:
print(recv, evt)
return super().notify(recv, evt)
class Btn(QPushButton):
def event(self, evt):
if evt.type() == QEvent.MouseButtonPress:
print("按鈕被點擊咯", evt)
return super().event(evt)
def mousePressEvent(self, *args, **kwargs):
print("鼠標(biāo)被按下了")
return super().mousePressEvent(*args, **kwargs)
app = App(sys.argv)
window = QWidget()
btn = Btn(window)
btn.setText("按鈕")
def slot():
print("按鈕被點擊了")
btn.pressed.connect(slot)
window.show()
sys.exit(app.exec_())