PySide6 事件的传播机制
在PySide6中,界面上的按钮(QPushButton)和QWidget部件都可以定义keyPressEvent
来处理键盘按键事件。当按键事件发生时,系统会根据事件的传播机制来确定哪个部件的keyPressEvent
方法将被执行。
事件的传播是从父部件向子部件传递的,意味着如果一个子部件没有处理事件,那么它的父部件可能会处理它。事件的传播遵循以下顺序:
- 首先,系统会检查具有焦点的部件是否定义了与事件相应的方法(例如
keyPressEvent
)。 - 如果有焦点的部件没有处理事件,系统会将事件传递给它的父部件,以查看父部件是否处理事件。
- 这个过程会一直向上追溯,直到找到一个处理事件的部件,或者到达顶级窗口。
基于这个传播机制,当界面上有一个按钮(QPushButton)和QWidget部件都定义了keyPressEvent
方法时,事件的处理顺序将取决于当前有焦点的部件。如果焦点在按钮上,那么按钮的keyPressEvent
方法将被执行;如果焦点在QWidget部件上,那么QWidget的keyPressEvent
方法将被执行。
示例代码
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QStyleFactory,
QPushButton, QVBoxLayout)
from PySide6.QtGui import QKeyEvent
class MainWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(300, 200)
self.setWindowTitle("事件传播机制")
self.button1 = QPushButton("Button 1")
self.button2 = QPushButton("Button 2")
self.button1.keyPressEvent = self.on_button1_keyPressEvent
layout = QVBoxLayout()
layout.addWidget(self.button1)
layout.addWidget(self.button2)
self.setLayout(layout)
def on_button1_keyPressEvent(self,event:QKeyEvent):
print("Button 1:",event.text())
def keyPressEvent(self,event:QKeyEvent):
print("QWidget:",event.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle(QStyleFactory.create("Fusion"))
window = MainWidget()
window.show()
sys.exit(app.exec())
这段代码中,定义了两个Button,其中 Button1 实现了keyPressEvent
方法,Button2 则无;QWidget 部件定义了keyPressEvent
方法;
当程序执行时,如果焦点在 Button1 上,按下按键时,Button1 的keyPressEvent
方法将被执行;当焦点在 Button2 上,按下按键时,由于 Button2 没有定义keyPressEvent
方法,所以由它的父部件,也就是 QWidget 来处理该事件;