Python / Odoo Developer

Welcome!

This community is for professionals and enthusiasts of our products and services. Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

0

PyQt Slot With Arguments [partial]

Avatar
Administrator

Open

A frequent question coming up when programming with PyQt is how to pass extra arguments to slots. After all, the signal-slot connection mechanism only specifies how to connect a signal to a slot - the signal's arguments are passed to the slot, but no additional (user-defined) arguments may be directly passed.

But passing extra arguments can be quite useful. You can have a single slot handling signals from multiple widgets, and sometimes you need to pass extra information.

One way to do this is using lambda. Here's a complete code sample:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyForm(QMainWindow):
    def __init__(self, parent=None):
        super(MyForm, self).__init__(parent)
        button1 = QPushButton('Button 1')
        button2 = QPushButton('Button 1')
        button1.clicked.connect(lambda: self.on_button(1))
        button2.clicked.connect(lambda: self.on_button(2))

        layout = QHBoxLayout()
        layout.addWidget(button1)
        layout.addWidget(button2)

        main_frame = QWidget()
        main_frame.setLayout(layout)

        self.setCentralWidget(main_frame)

    def on_button(self, n):
        print('Button {0} clicked'.format(n))

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = MyForm()
    form.show()
    app.exec_()

Note how the on_button slot is used to handle signals from both buttons. Here we use lambda to pass the button number to the slot, but anything can be passed - even the button widget itself (suppose the slot wants to deactivate the button that sent the signal).

There's an alternative to lambda - using functools.partial. We can replace the connection lines with:

button1.clicked.connect(partial(self.on_button, 1))
button2.clicked.connect(partial(self.on_button, 2))
Avatar
Discard