PyQt6中Shift+滚轮触发QTextEdit水平滚动的事件过滤器仅在文本边界生效的问题求助
PyQt6中Shift+滚轮触发QTextEdit水平滚动的事件过滤器仅在文本边界生效的问题求助
各位大佬好,我遇到了一个PyQt6的问题,想请教下大家:
我做了一个带有多个QTextEdit的PyQt6应用,这些QTextEdit里的文本有时候会超出一行的可见范围。本来Shift+滚轮是用来垂直滚动的,但我想改成按下Shift时用滚轮实现水平滚动,而且希望和垂直滚动的默认行为一样——只要鼠标悬停在QTextEdit上就能触发,不用点击激活它。
为了实现这个需求,我写了一个事件过滤器:先检测Shift键是否按下,再通过QApplication.widgetAt找到鼠标下方的控件,然后向上遍历父控件层级,直到找到QTextEdit(这样就不用维护所有QTextEdit的引用列表来比对,我觉得这个思路更灵活)。
我的事件过滤器代码如下:
def eventFilter(self, obj, event): if isinstance(event, QWheelEvent) and QApplication.keyboardModifiers() == Qt.KeyboardModifier.ShiftModifier: widget_under_mouse = QApplication.widgetAt(event.globalPosition().toPoint()) while widget_under_mouse is not None: if isinstance(widget_under_mouse, QTextEdit): break widget_under_mouse = widget_under_mouse.parent() # 向上遍历控件层级 if isinstance(widget_under_mouse, QTextEdit): if h_scroll_bar := widget_under_mouse.horizontalScrollBar(): new_value = h_scroll_bar.value() - event.angleDelta().y() h_scroll_bar.setValue(new_value) return True return super().eventFilter(obj, event)
现在遇到的问题是:这个过滤器只有当文本滚动到QTextEdit的顶部或底部边界时才会触发,在正常的滚动范围内完全没反应。
我已经尝试过把过滤器安装在不同的位置:
- 直接安装在
QApplication实例上:app.installEventFilter(ScrollFilter())(ScrollFilter是继承自QObject的事件过滤器类) - 安装在主窗口实例上:
self.installEventFilter(self) - 直接安装在单个QTextEdit控件上:
self.my_text_edit.installEventFilter(self)
但不管装在哪里,问题都一模一样。我猜测可能是没正确处理那个匿名控件的引用?不过我必须找到最上层的QTextEdit,因为应用里还有其他控件,不能让它们也触发这种水平滚动。
有没有大佬能帮我分析下问题出在哪?怎么修改才能让Shift+滚轮在QTextEdit的任何滚动状态下都能触发水平滚动?
内容来源于stack exchange
相关产品推荐
相关产品推荐

