Search code examples
pythonparameterspyqtpysidesignals-slots

QAction triggered signal is not passing checked parameter


I have made a menu bar with a QAction which is set to checkable

self.display_features_action = QtGui.QAction("Show Features", parent)
self.display_features_action.setCheckable(True)
self.display_features_action.setChecked(True)

Then I connect to this

class MyClass:
    def __init__(....)
         ....
         self.display_features_action.triggered.connect(self.my_slot)

    def my_slot(self, checked)
         ....

But I get a runtime error that the my_slot method takes to arguments, when only one is supplied. Why isnt the checked parameter sent with the signal?


Solution

  • It seems that the treatment of signals with default parameters (such as triggered and clicked) is different in PySide to what it is in PyQt. The former won't allow any positional arguments in the receiving slot, but the latter will happily throw away unused parameters without complaint.

    In both PySide and PyQt, signals with default parameters effectively have two overloads: a "no-op" version which sends nothing (or, in PyQt, always sends False), and an "active" version, which sends the current checked state.

    The "no-op" version is the default, so to get the "active" version, you have to explicitly select it, like this:

        action.triggered[bool].connect(slot)
    

    As for the slot signature: in PySide, the most robust solution would probably be this:

        def slot(self, checked=False):