Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Callback function tkinter button with variable parameter

from tkinter import *

F=Tk()

i=1
while i<10:
    newButton = Button(F,text="Show Number",command=lambda:showNumber(i))
    newButton.pack(side=TOP)
    i+=1

def showNumber(nb):
    print(nb)

F.mainloop()

All buttons return 10. Why ?
I want button 1 return 1, button 2 return 2...
Thank you very much for helping me

like image 611
superyo40 Avatar asked Oct 30 '13 21:10

superyo40


1 Answers

Your anonymous lambda functions are can be though of as closures (as @abernert points out, they're not actually closures in Python's case) - they "close over" the variable i, to reference it later. However, they don't look up the value at the time of definition, but rather at the time of calling, which is some time after the entire while loop is over (at which point, i is equal to 10).

To fix this, you need to re-bind the value of i to a something else for the lambda to use. You can do this in many ways - here's one:

...
i = 1
while i < 10:
    # Give a parameter to the lambda, defaulting to i (function default
    # arguments are bound at time of declaration)
    newButton = Button(F, text="Show Number",
        command=lambda num=i: showNumber(num))
    ...
like image 171
voithos Avatar answered Oct 16 '22 11:10

voithos