测试QWidget是否接收鼠标输入



我最近在我的PyQt5应用程序中引入了一个错误。我有一个QWidget,我在其中渲染游戏,并将其用作QMainWindow中的centralWidget,我称之为Canvas。我想在画布上呈现一些文本,所以我制作了下面的QWidget,现在我用它作为我的centralWidget。它在画布上堆叠一个QLabel。

class CentralWidget(PyQt5.QtWidgets.QWidget):
def __init__(self, content: Canvas) -> None:
super().__init__()
self.content = content
content.setParent(self)
self.label = PyQt5.QtWidgets.QLabel('', self)
self.label.setObjectName('notification_label')
self.label.setStyleSheet("QLabel { color : white; font-size: 50px }")
self.label.setAlignment(PyQt5.QtCore.Qt.AlignCenter)
def resizeEvent(self, event: PyQt5.QtGui.QResizeEvent) -> None: # pylint: disable=invalid-name
self.label.setGeometry(0, 0, event.size().width(), event.size().height())
self.content.setGeometry(0, 0, event.size().width(), event.size().height())

这渲染得很好,但它导致我的画布停止接收鼠标输入。我意识到我的QLabel正在拦截所有输入,我通过添加self.label.setAttribute(PyQt5.QtCore.Qt.WA_TransparentForMouseEvents)解决了这个问题。我想我应该加一个回归测试。

我尝试使用QTest和QApplication将鼠标事件发送到QMainWindow,希望它们能冒泡下来,但事件似乎从未通过QMainWindow。然后我尝试将事件发送到我的Canvas,当我这样做时,我看到它们会弹出到QMainWindow。我不想测试Canvas是否正确处理输入,我想测试输入事件是否被路由到Canvas。有没有办法在单元测试中验证这一点?

由于这些鼠标事件是向上而不是向下冒泡的,我认为QT必须通过找到发生鼠标输入的最低QWidget来处理鼠标输入,然后向其发送鼠标事件,这表明了一个涉及QWidget:childAt和/或QApplication::widgetAt的解决方案。果不其然,QWidget::childAt忽略了WA_TransparentForMouseEvents属性集的窗口小部件,所以我使用QWidget::childAt编写了一个测试。

https://code.woboq.org/qt5/qtbase/src/widgets/kernel/qwidget.cpp.html#_ZNK14QWidgetPrivate22childAtRecursiveHelperERK6QPointb

最新更新