You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide2中设置并清除QGraphicsTextItem焦点后Tab键无法触发KeyPressEvent的原因

问题:双击QGraphicsTextItem后Tab键无法触发主部件的KeyPressEvent

双击QGraphicsTextItem后,Tab键(目前未发现其他键受影响)不再触发主部件的KeyPressEvent。推测该问题与PySide2的焦点处理机制有关,可能关联QtCore.Qt.FocusReason中的TabFocusReason。

复现代码

import sys
from PySide2 import QtWidgets, QtCore, QtGui

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        # 创建QGraphicsScene
        self.scene = QtWidgets.QGraphicsScene()
        
        # 创建QGraphicsTextItem
        text_item = QtWidgets.QGraphicsTextItem("Example")
        text_item.setDefaultTextColor(QtCore.Qt.blue)  # 可选设置文本颜色
        self.scene.addItem(text_item)
         
        # 创建QGraphicsView
        self.view = QtWidgets.QGraphicsView(self.scene)
        self.setCentralWidget(self.view)

        # 保存文本项供后续使用
        self.text_item = text_item

    def keyPressEvent(self, event):
        """调试用:按键触发事件时打印其枚举值"""
        print(event.key())
        super().keyPressEvent(event)

    def mouseDoubleClickEvent(self, event):
        # 获取点击的项
        scene_pos = self.view.mapToScene(event.pos())
        item = self.scene.itemAt(scene_pos, QtGui.QTransform())

        if isinstance(item, QtWidgets.QGraphicsTextItem):
            # 最简复现bug的操作
            item.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
            item.setFocus(QtCore.Qt.MouseFocusReason)
        
            item.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
            item.clearFocus()
        
            # 修改文本内容,标记双击事件已触发
            item.setPlainText("changed")

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

问题原因

临时给QGraphicsTextItem设置TextEditorInteraction交互标志并赋予焦点后,即便后续清除了焦点和交互标志,Qt内部的焦点处理状态(尤其Tab键的焦点切换逻辑)未完全恢复,导致Tab键事件被拦截,无法传递到主窗口的keyPressEvent。

解决方案

完成文本项操作后,手动将焦点重新设置回主窗口或QGraphicsView,确保焦点回归正确部件,恢复正常的按键事件传递链。

修改后的mouseDoubleClickEvent方法如下:

def mouseDoubleClickEvent(self, event):
    # 获取点击的项
    scene_pos = self.view.mapToScene(event.pos())
    item = self.scene.itemAt(scene_pos, QtGui.QTransform())

    if isinstance(item, QtWidgets.QGraphicsTextItem):
        # 最简复现bug的操作
        item.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
        item.setFocus(QtCore.Qt.MouseFocusReason)
    
        item.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        item.clearFocus()
    
        # 修改文本内容,标记双击事件已触发
        item.setPlainText("changed")
        
        # 手动将焦点设置回主窗口,恢复Tab键事件传递
        self.setFocus(QtCore.Qt.MouseFocusReason)

验证效果

修改后双击文本项,再按Tab键,主窗口的keyPressEvent会正常打印Tab键的枚举值(16),说明事件已正常触发。

内容的提问来源于stack exchange,提问作者Kevin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:45:04