信号与槽机制是对事件机制的高级封装
事件机制更偏向于底层
每个 Qt 应用程序对应一个 QAppliation 对象
一个应用程序拥有几个消息队列,应用程序的消息循环,就是在处理这些队列中的消息
用户的操作会产生各种事件消息
消息首先会被操作系统接收,然后操作系统会把消息分发到对应的各应用程序的“消息队列”中
比如分为两个队列:系统产生的消息组成的队列(鼠标事件、键盘事件、拖放事件),程序内部产生的消息组成的队列(定时器事件、绘屏事件)
消息循环:
不断地按顺序检测消息队列中是否有消息
若发现“事件消息”,则包装成“QEvent 对象”进行分发处理
将事件接收者(receiver)和事件对象(evt)传递给 QApplication 对象的 notify(receiver, evt) 方法进行处理
QApplication 对象是否安装事件过滤器(事件过滤器可设置多个,但会按照设置的逆序进行分发)
- 是:QApplication 对象 n 个事件过滤器 eventFilter(watched, evt) 方法的返回值,若为 True 则不再继续分发(告诉系统该事件已被处理)
- 否:分发给 receiver 对象的 event(evt) 方法,此方法会根据 evt 的事件类型分发给 receiver 具体的事件函数
如 mousePressEvent(evt)、mouseReleaseEvent(evt)、mouseClickEvent(evt) 等
部分控件在这些具体的事件方法中,可能发射了对应的信号(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("鼠标被按下了")
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_())