0

Here is my GUI and code shown as below, expected result is:

one -- print 0

two -- print 1

three -- print 2

However, the program prints "2", no matter which check-box get selected. How can I fix it?

enter image description here

from Tkinter import *
root = Tk()
my_list = ['one', 'two', 'three']
cb_value = []
cb = []


def show_index(idx):
    print idx

for idx, each in enumerate(my_list):
    cb_value.append(IntVar())
    cb.append(Checkbutton(root, text=each, variable=cb_value[idx], command=lambda: show_index(idx)))
    cb[idx].pack()
root.mainloop()

thanks!

vicd
  • 573
  • 4
  • 10

1 Answers1

3

use lambda idx=idx:show_index(idx) instead.

The "problem" is that python functions only bind the name of a variable in the closure (see https://stackoverflow.com/a/11953356/748858 for instance). They actually look up the value from the appropriate place when the function is called. Your functions are never being called until the loop has finished and at that point, idx has the value of 2. Each of your lambda functions, when called are looking up idx and so they're getting the value of 2. The trick that I show above makes idx a variable local to the function (rather than having it picked up via a closure). Since I do this by using a keyword argument, and keyword arguments are evaluated when the function is created, you always get the proper value.

Community
  • 1
  • 1
mgilson
  • 300,191
  • 65
  • 633
  • 696