The anonymous lambda: doit(dic[key]) function lambda: doit(dic[key]) does not evaluate key until the function is called. By this time, for-loop , and the for-loop key variable refers to the last key in dic .
When an anonymous function is called (when you click the button), key scanned in the global namespace and the current key value is returned.
To avoid this error, you can use the default argument in the lambda expression:
for key in dic: btn = QPushButton(key, self) btn.clicked.connect(lambda key=key: doit(dic[key])) vbox.addWidget(btn)
The default arguments are evaluated at the time of definition, not at the time of calling the lambda. By doing so, key looked up in the local namespace of the anonymous function, and not in the global namespace, and since the value of the local namespace is set to the default value, which is different for each pass through the for-loop, you will get the correct value key .
This is also explained in this SO answer .
source share