【问题标题】:Testing that a QWidget receives mouse input测试 QWidget 接收鼠标输入
【发布时间】:2023-03-21 06:53:01
【问题描述】:

我最近在我的 PyQt5 应用程序中引入了一个错误。我有一个 QWidget,我在其中渲染游戏,并将其用作 QMainWindow 中的 centralWidget,我称之为 Canvas。我想在 Canvas 上渲染一些文本,所以我制作了以下 QWidget,现在我将其用作我的 centralWidget。它在 Canvas 上堆叠一个 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。然后我尝试将事件发送到我的画布,我看到当我这样做时它们会冒泡到 QMainWindow。我不是想测试 Canvas 是否正确处理输入,我想测试输入事件是否被路由到 Canvas。有没有办法在单元测试中验证这一点?

【问题讨论】:

标签: unit-testing pyqt5


【解决方案1】:

由于这些鼠标事件冒泡而不是向下冒泡,我认为 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

【讨论】:

    猜你喜欢
    • 2017-08-26
    • 1970-01-01
    • 2022-01-20
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 2021-11-26
    • 2011-06-01
    相关资源
    最近更新 更多