【问题标题】:QAction.setEnabled(False) unexpected behaviourQAction.setEnabled(False) 意外行为
【发布时间】:2021-09-24 15:46:25
【问题描述】:

我已经确定禁用QAction 实际上并不能阻止代码在其上运行activate(),这让我感到好奇。所以我想做一个辅助子类:

class DeactivatableAction(QtWidgets.QAction):
    def activate(self, event):
        if self.isEnabled():
            super().activate(event)

在实践中,这似乎适用于我正在开发的应用程序。然后我想包括对这个功能的测试(pytest):

@unittest.mock.patch('PyQt5.QtWidgets.QAction.activate')
def test_deactivatable_action_should_only_superactivate_if_enabled(mock_super):
    import gen_fmwrk.deactivatable_action as d_action
    
    QtWidgets.QApplication([]) # without this, I get a complaint about "Application not initialized"
    
    da = d_action.DeactivatableAction()

    da.setEnabled(False)
    # da.setDisabled(True) - NB same effect as previous line

    assert not da.isEnabled() # this fails!
    da.activate(None)
    assert not mock_super.called # this also fails

我意识到这是一种运行 PyQt5 代码的无实体方式......但我仍然希望能够在这样的 pytest 上下文中禁用 QAction。出了什么问题,有解决办法吗?

【问题讨论】:

  • 关于您的“好奇”点:禁用操作不会以编程方式限制其功能,它只会阻止用户交互,就像小部件一样:如果禁用行编辑,您仍然可以使用 setText .
  • 公平点...但您可能希望选择使用可停用的操作。争论的焦点仍然是......
  • 关于缺少 QApplication 的“投诉”不仅仅是一个毫无意义的警报。所有与 UI 直接相关的元素(又名:正在运行的系统,包括屏幕、DPI 等)都需要一个现有的 QApplication 实例,以便正确查询它与 UI 相关的方面。 QAction(至少在 Qt6 之前,它被移动到 QtGui)是一个 QtWidget 类,因此它需要一个 QtWidgets 应用程序(又名 QApplication)。即使没有分配,您的代码也不会“抱怨”,因为应用程序的实例在某个时候存在,但您的代码无法工作,因为它不再存在。

标签: python testing pyqt5 pytest python-unittest


【解决方案1】:

问题是QtWidgets.QApplication([]) 没有分配给变量,因此它不会被正确构造,从而导致意外行为。改为

app = QtWidgets.QApplication([])

【讨论】:

    猜你喜欢
    • 2018-03-11
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 2019-05-01
    • 2011-07-15
    相关资源
    最近更新 更多