重写的 QGraphicsView keyPressEvent 从焦点 QGraphicsWidgets 窃取事件

Posted

技术标签:

【中文标题】重写的 QGraphicsView keyPressEvent 从焦点 QGraphicsWidgets 窃取事件【英文标题】:Overridden QGraphicsView keyPressEvent steals events from focused QGraphicsWidgets 【发布时间】:2020-02-06 20:16:23 【问题描述】:

我已经为某些按键事件构建了具有定义行为的自定义 QGraphicsView。该视图显示QGraphicsSceneQGraphicsProxyWidgets

问题是,一旦我覆盖视图中的keyPressEvent,事件就不会传递给小部件,因此我无法在文本框中输入。我希望小部件在获得焦点时窃取 keyPressEvents。

我尝试在代理小部件上设置 ItemIsFocusable 标志并将焦点策略设置为 StrongFocus 等等。到目前为止没有运气。

有人有什么建议吗?我要解决这个问题了吗?感谢您的观看!

import sys
from Qt import QtWidgets, QtCore


class CustomView(QtWidgets.QGraphicsView):

    def __init__(self, parent):

        super(CustomView, self).__init__(parent)

    def keyPressEvent(self, event):

        if event.key() in (QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace):
            print('Deleting')



app = QtWidgets.QApplication(sys.argv)

groupBox = QtWidgets.QGroupBox("Contact Details")
numberLabel = QtWidgets.QLabel("Telephone number")
numberEdit = QtWidgets.QLineEdit()

layout = QtWidgets.QFormLayout()
layout.addRow(numberLabel, numberEdit)
groupBox.setLayout(layout)

scene = QtWidgets.QGraphicsScene()
proxy = scene.addWidget(groupBox)
proxy.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable)
proxy.setFocusPolicy(QtCore.Qt.StrongFocus)

view = CustomView(scene)
view.show()

app.exec_()

【问题讨论】:

【参考方案1】:

如果您覆盖一个方法并且不调用父类的实现,那么您将消除默认行为,在您的情况下将键盘事件发送到项目。

解决办法是通过super调用父类的keyPressEvent方法:

def keyPressEvent(self, event):
    super(CustomView, self).keyPressEvent(event)
    if event.key() in (QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace):
        print('Deleting')

【讨论】:

太棒了,谢谢@eyllanesc!为了防止小部件聚焦时出现这种情况,我添加了以下 if 语句:if self.scene().focusItem() is None:

以上是关于重写的 QGraphicsView keyPressEvent 从焦点 QGraphicsWidgets 窃取事件的主要内容,如果未能解决你的问题,请参考以下文章

QGraphicsView 自定义滚动条

qgraphicsview图片下方添加文字

如何在 QGraphicsView::Scale 之后调整 QGraphicsView 的大小

QGraphicsView::NoViewportUpdate 不起作用

在 QGraphicsView 中移动项目

QGraphicsView:如何高效获取QGraphicsItems的视口坐标?