Lambda i = i: foo (i) in for loop not working

Read this first . It's about lambda x=x: foo(x) catching x even in a for loop.

This is a window with a label and two buttons generated in a for loop. When the button is pressed, this name appears in the label.

If we use the usual lambda: label.setText("button -- " + str(i)) , then the result will be the last i in the loop, regardless of which button is pressed:
lambda: foo (i)
And it is right.

When we go to lambda i=i: label.setText("button -- " + str(i)) (snipet) and expect that everything will be fine now, the result:
lambda i = i: foo (i)]
Lying!

Where does this False come from?

 import sys from PyQt4.QtGui import * class MainWindow(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) vbox = QVBoxLayout(self) # label for action label = QLabel('') vbox.addWidget(label) # adding buttons for i in range (1, 3): btn = QPushButton(str(i)) btn.clicked.connect( lambda i=i: label.setText("button " + str(i)) ) vbox.addWidget(btn) app = QApplication(sys.argv) myapp = MainWindow() myapp.show() sys.exit(app.exec_()) 

Why doesn't this solution work as it should? What does this False mean?

I know that you can do foo_factory as in the first link, but the question is what is wrong with lambda i=i: foo(i)

+4
source share
2 answers

I do not have PyQt4 installed for testing at this very moment, but it seems obvious to me that when you call your lambda call, they give it an argument. i then equals any argument, not the default. Try this and tell me if this works (or at least modifies the result):

 btn.clicked.connect( lambda throw_away=0, i=i: label.setText("button " + str(i)) ) 
+4
source

The clicked signal passes a boolean argument to your connected lambda slot.
Documentation

What you are trying to accomplish is best done as follows:

 btn.clicked.connect( lambda clicked, i=i : label.setText("button " + str(i)) ) 
+2
source

All Articles