【发布时间】: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