mike rodent
mike rodent

Reputation: 15692

QAction.setEnabled(False) unexpected behaviour

I have ascertained that making a QAction disabled does not in fact prevent code from being able to run activate() on it, which strikes me as curious. So I want to make a helper subclass:

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

This seems to work in an app I'm working on, in practice. Then I wanted to include testing of this functionality (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

I realise this is a sort of disembodied way to run PyQt5 code... but I'd still expect to be able to disable a QAction in a pytest context like this. What's going wrong, and is there a solution?

Upvotes: 0

Views: 303

Answers (1)

eyllanesc
eyllanesc

Reputation: 244301

The problem is that QtWidgets.QApplication([]) is not assigned to a variable so it will not be constructed correctly causing unexpected behavior. Change to

app = QtWidgets.QApplication([])

Upvotes: 2

Related Questions