0

I have created a custom pyQT5 widget with a label and a pushbutton and I want to connect the "clicked" event to a callback function. The widgets are created in a for loop over a list of id's and I need to pass the corresponding id to the callback function.

My problem is that the id in the callback is always on the last list item, I guess I just pass the reference to the id object to the for loop and it holds the last id after all the widgets are created.

Here is my example code:

from PyQt5 import QtWidgets
import sys


class MyWidget (QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.myButton = QtWidgets.QPushButton()
        self.myLabel = QtWidgets.QLabel()
        self.myLayout = QtWidgets.QHBoxLayout()
        self.myLayout.addWidget(self.myButton)
        self.myLayout.addWidget(self.myLabel)
        self.setLayout(self.myLayout)

    def setText(self, text):
        self.myLabel.setText(str(text))

    def setButtonText(self, text):
        self.myButton.setText(str(text))

    def connectButton(self, action):
        self.myButton.clicked.connect(action)


class myMainWindow (QtWidgets.QMainWindow):
    def __init__(self):
        super(myMainWindow, self).__init__()
        data = [1, 2, 3, 4, 5]

        self.myListWidget = QtWidgets.QListWidget(self)
        for id in data:
            myCustomWidget = MyWidget()
            myCustomWidget.setText(id)
            myCustomWidget.setButtonText(id)
            myCustomWidget.connectButton(
                lambda: self.buttonAction(id))

            myListWidgetItem = QtWidgets.QListWidgetItem(self.myListWidget)

            myListWidgetItem.setSizeHint(myCustomWidget.sizeHint())

            self.myListWidget.addItem(myListWidgetItem)
            self.myListWidget.setItemWidget(
                myListWidgetItem, myCustomWidget)
        self.setCentralWidget(self.myListWidget)

    def buttonAction(self, id):
        # do something with id
        print(f'My Id is: {id}')


app = QtWidgets.QApplication([])
window = myMainWindow()
window.show()
sys.exit(app.exec_())

When I click the Buttons 1-5 I get this output:

My Id is: 5
My Id is: 5
My Id is: 5
My Id is: 5
My Id is: 5

Expected output:

My Id is: 1
My Id is: 2
My Id is: 3
My Id is: 4
My Id is: 5

How can I make sure the callback is called with the correct id?

HaWe
  • 1
  • 1
  • 1
    Does this answer your question? [lambda in for loop only takes last value](https://stackoverflow.com/questions/33983980/lambda-in-for-loop-only-takes-last-value) – mugiseyebrows Apr 15 '21 at 12:02
  • The answer in the linked question did not work for me. But I found a solution in a question linked there.:) – HaWe Apr 15 '21 at 15:20

0 Answers0