1

I'm struggling to pass contextual information with a button clicked signal.

Here's a minimal example, which creates a widget with several numbered buttons. The message box should display the corresponding number when each button is clicked.

import sys
from PySide6 import QtCore, QtWidgets, QtGui

class Gui(QtWidgets.QWidget):
    def __init__(self, parent=None, n_buttons=9):
        super(Gui, self).__init__(parent)
        self._mainLayout = QtWidgets.QVBoxLayout()
        self.setLayout(self._mainLayout)
        for n in range(n_buttons):
            btn = QtWidgets.QPushButton(str(n))
            self._mainLayout.addWidget(btn)
            btn.clicked.connect(
                lambda val=n: self.showMsg(val)
            )

    def showMsg(self, message):
        msg = QtWidgets.QMessageBox()
        msg.setText(str(message))
        msg.setStandardButtons(QtWidgets.QMessageBox.Ok)
        msg.exec()

def main():
    app = QtWidgets.QApplication([])
    view = Gui()
    view.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Instead the message box shows "False" whichever button I click.

I've tried implementing the signal using a lambda function, following the explanation here: https://www.learnpyqt.com/tutorials/transmitting-extra-data-qt-signals/

Thanks for any advice!

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Change to `lambda clicked, val=n: self.showMsg(val)` and see [this answer](https://stackoverflow.com/a/35821092) – musicamante Mar 16 '21 at 20:38
  • 1
    1) Add `from functools import partial` and change `btn.clicked.connect(lambda val=n: self.showMsg(val))` to `btn.clicked.connect(partial(self.showMsg, n))` OR 2) `btn.clicked[bool].connect(lambda checked, val=n: self.showMsg(val))` – eyllanesc Mar 16 '21 at 20:40
  • @musicamante That does not work in PySide (test it and you will check), in PySide you must use partial. – eyllanesc Mar 16 '21 at 20:41
  • @eyllanesc good to know, thanks. Do you have some resource/message/post/doc to read about that difference? – musicamante Mar 16 '21 at 20:50
  • 1
    @musicamante There is nothing documented but I think that the cause is that pyside counts the args of the callable and according to it chooses the signature, it seems to me a bug. – eyllanesc Mar 16 '21 at 20:52
  • @eyllanesc makes sense (the explanation). It seems some sort of a bug to me too. – musicamante Mar 16 '21 at 20:57
  • For the OP: pyqt is different to pyside – eyllanesc Mar 16 '21 at 20:58
  • @eyllanesc thanks for the heads-up on PySide vs PyQt - I hadn't really appreciated the difference. Are the APIs generally identical? Would you recommend one over the other? – Richard Guy Mar 17 '21 at 21:16

0 Answers0