+ 5

[SOLVED] How to assign different function-parameters to different buttons?

I have a tkinter label widget at the top line and 5 generated buttons underneath it. All buttons shall call the same function, but the buttons have to give different values to the function. The function has to change the text in the label widget. I have already understood that the 'command'-parameter of the button can only store the function name. If I want to give an individual value to the function, then I have to use the lambda function. But the program does not work as intended. Could anybody correct the code, please? The code follows here: https://code.sololearn.com/c9Gt98BDzJiY/?ref=app

19th Jul 2020, 8:03 PM
Jan Markus
6 odpowiedzi
+ 3
Well, your solution with 'exec' function doesn't seem clean. Indeed, in Python, we try to avoid as much as possible the use of the 'exec' function, and in that case it is not needed, since you can solve your problem like this : Button(win, text=str(i), command=(lambda i=i: put(i)))
26th Jul 2020, 7:40 AM
Théophile
Théophile - avatar
+ 3
Jan Markus, would you please explain, why you prefer your solution to the one offered by Theophile?
26th Jul 2020, 7:39 AM
Kurt Sicht
Kurt Sicht - avatar
+ 3
Kurt Sicht It is totally easy: I made a mistake somewhere and I was not able to adapt Théophile 's advice onto my case. So I searched for a working example. @Théophile : Yes, I was aware of the fact that one is NOT ALLOWED UNDER ALL CIRCUMSTANCES to use exec() whenever possible because of safety risks. But I did not know how to help me. This was the only way to get a working code. And after hours of trying I was heavily glad that I have found at least one working example. I tried it now with today's suggestion of @Théophile and it works as intended. Many thanks for your help.
26th Jul 2020, 10:44 AM
Jan Markus
+ 3
I have improved the example now according to the suggestion of Théophile . https://code.sololearn.com/ctZoRjkMfsvd/?ref=app What I did not know was the exact syntax of the lambda expression, especially with the 'i=i'-thing.
26th Jul 2020, 10:51 AM
Jan Markus
+ 1
command = (lambda i=i: put(i)) Lambdas are capturing the scope in which they are defined. So at the end of the loop, i is 4 and all commands are doing put(i)... So all commands do the same thing. The solution is to create create a local variable, wich will not refer to i but which will contains a reference to the value of i. The only mean to achieve that is to use optional argument. By doing this, the local variable will be a reference to the value hold by i. However, since integers are immutable, it's like if your local variable contains a copy of the value of i.
19th Jul 2020, 8:35 PM
Théophile
Théophile - avatar
- 1
After doing some research I have found an answer to my question: The trick is, that you have to create the instruction as a string and run it with the exec()-function. I don't know wheather this is the most clean way to do this, but at least it works as intended. Here is my revised code example: https://code.sololearn.com/c6TIwkMY29vk/?ref=app
26th Jul 2020, 4:45 AM
Jan Markus