-1

I have a dictionary of QPushButtons, I am trying to change the text when a certain push button is pressed, but it keeps only changing the last button. I think the issue is that every time 3 gets passed, I have no idea why that would be the case though. My code looks like this:

class App(QWidget):
    def __init__(self):
        super().__init__()

        self.buttons = {}

        for x in range(1, 4):
            self.buttons[x] = QPushButton(self)
            self.buttons[x].setText("TestButton")
            self.buttons[x].resize(70, 30)
            self.buttons[x].move(40, 40*x)
            self.buttons[x].clicked.connect(lambda: self.ButtonPressed(x))

        self.show()

    def ButtonPressed(self, x):
        self.buttons[x].setText("Text Changed!")
Weegloogi
  • 5
  • 1
  • change `self.buttons[x].clicked.connect(lambda: self.ButtonPressed(x))` to `self.buttons[x].clicked.connect(lambda _, x=x: self.ButtonPressed(x))` – S. Nick Jan 13 '20 at 10:37

1 Answers1

0

the variable x in your lambda is referencing the x in your loop. So, its value will change after each iteration (and will take the last value at the end of your loop). You can see that if you print the address of x in ButtonPressed:

    def ButtonPressed(self, x):
        self.buttons[x].setText("Text Changed!")
        print(hex(id(x)), x)

All you have to do is to mask x with a local parameter. You can use partial from functools for that:

fct = partial(self.ButtonPressed, x=x)
self.buttons[x].clicked.connect(fct)

Or you can also add parameter to your lambda:

self.buttons[x].clicked.connect(lambda _, local_x=x: self.ButtonPressed(local_x))

The first parameter _ corresponds to the self parameter of ButtonPressed.

Dimitry Ernot
  • 6,256
  • 2
  • 25
  • 37