Search code examples
pythonpyqtsignals-slots

How to pass arguments to callback functions in PyQt


I have around 10 QAction (this number will vary in runtime) in a toolbar, which all will do same thing, but using different parameters. I am thinking to add parameter as an attribute to QAction object, and then, QAction's triggered signal will also send object's itself to the callback function, so that I could get required parameters for the function. I have actually 2 questions about this:

  • Can it be done?
  • Is there a better way of doing this?

Solution

  • You can send the action object itself using a signal mapper. However, it may be better to simply send an identifier and do all the work within the signal handler.

    Here's a simple demo script:

    from PyQt4 import QtGui, QtCore
    
    class Window(QtGui.QMainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            self.mapper = QtCore.QSignalMapper(self)
            self.toolbar = self.addToolBar('Foo')
            self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
            for text in 'One Two Three'.split():
                action = QtGui.QAction(text, self)
                self.mapper.setMapping(action, text)
                action.triggered.connect(self.mapper.map)
                self.toolbar.addAction(action)
            self.mapper.mapped['QString'].connect(self.handleButton)
            self.edit = QtGui.QLineEdit(self)
            self.setCentralWidget(self.edit)
    
        def handleButton(self, identifier):
            if identifier == 'One':
                text = 'Do This'
            elif identifier == 'Two':
                text = 'Do That'
            elif identifier == 'Three':
                text = 'Do Other'
            self.edit.setText(text)
    
    if __name__ == '__main__':
    
        import sys
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.resize(300, 60)
        window.show()
        sys.exit(app.exec_())