First read this. It is about lambda x=x: foo(x)
catching x even in for
loop.
This is a window with label and two buttons generated in for
loop. When button is clicked, it name appears in label.
If we use usual lambda: label.setText("button -- " + str(i))
, then the result is last i
in the loop, no matter what button is pressed:
And this is right.
When we change to lambda i=i: label.setText("button -- " + str(i))
(snipet) and expect that now it will be everything ok, the result is:
False!
Where this False
comes 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 this solution is not working as it should be? What this false
means?
I know that you can make foo_factory
, as in first link, but the question is what is wrong with lambda i=i: foo(i)
I don't have PyQt4 installed to test at this very instant, but it seems clear to me that when your lambda callback is called, it's being given an argument. i
is then equal to whatever the argument is, instead of the default value. Try this and tell me if it works (or if it at least changes the output):
btn.clicked.connect( lambda throw_away=0, i=i: label.setText("button " + str(i)) )
Signal "clicked" passes a boolean argument to your connected lambda slot.
Documentation
What you are trying to accomplish is better done by this:
btn.clicked.connect( lambda clicked, i=i : label.setText("button " + str(i)) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With