PySide6中eventFilter无法获取QHoverEvent的position()问题
PySide6监听Viewport悬停位置的解决方案
从PySide2迁移到PySide6时,通过eventFilter监听部件viewport()的悬停位置会遇到事件类型不匹配的问题:PySide6中传递的是QEvent基类实例,而非PySide2中的QHoverEvent子类,导致无法直接调用position()方法。
解决方法
需要将QEvent类型的事件对象转换为QHoverEvent子类,才能访问position()方法。具体修改eventFilter方法即可:
def eventFilter(self, obj, event): if obj == self.tree_view.viewport(): if event.type() == QtCore.QEvent.HoverMove: # 将QEvent转换为QHoverEvent hover_event = QtGui.QHoverEvent(event) print(hover_event.position()) return super().eventFilter(obj, event)
完整修改后的代码
from PySide6 import QtGui, QtWidgets, QtCore class TestWindow(QtWidgets.QMainWindow): def __init__(self): super(TestWindow, self).__init__() self.setMinimumSize(500, 500) center_widg = QtWidgets.QWidget(self) self.setCentralWidget(center_widg) layout = QtWidgets.QVBoxLayout() self.centralWidget().setLayout(layout) self.tree_view = QtWidgets.QTreeView() model = QtGui.QStandardItemModel() model.setHorizontalHeaderLabels(["colm_01", "colm_02"]) self.tree_view.setModel(model) self.tree_view.viewport().setAttribute(QtCore.Qt.WidgetAttribute.WA_Hover) self.tree_view.viewport().installEventFilter(self) layout.addWidget(self.tree_view) def eventFilter(self, obj, event): if obj == self.tree_view.viewport(): if event.type() == QtCore.QEvent.HoverMove: hover_event = QtGui.QHoverEvent(event) print(hover_event.position()) return super().eventFilter(obj, event) def main(): app = QtWidgets.QApplication([]) dialog = TestWindow() dialog.show() app.exec_() if __name__ == "__main__": main()
原因说明
Qt6对事件系统做了优化调整,事件过滤器中默认传递的是QEvent基类对象,需要手动转换为对应子类才能访问子类特有的属性和方法;而Qt5(对应PySide2)中事件过滤器会直接传递子类事件实例,因此无需转换即可调用position()。
内容的提问来源于stack exchange,提问作者Moobius
相关产品推荐
相关产品推荐

