Python Tkinter OptionMenu add a command to multiple OptionMenus

感情迁移 提交于 2019-12-11 06:55:56

问题


Basically I have a series of OptionMenus that are created in a loop, but is currently empty:

option_menu = []
for ii in range(jj):
    option_menu.append([])  
    for ll in range(kk):   
        option_menu[ii].append(OptionMenu(frame,tkinter_text_var[ii][ll],''))

Then elsewhere I use a checkbox to set the values along the lines of:

for ii in range(jj):
    for ll in range(kk):   
        option_menu[ii][ll]["menu"].add_command(label = name_from_box.get(), command = lambda: tkinter_text_var[ii][ll].set(name_from_box.get()))

This works to populate all of the OptionMenus properly, but when I select a value in any of the OptionMenus, it only sets option_menu[jj][kk] (i.e. that last one made).

So what have I done wrong?


回答1:


This is a very common question involving closures. Look at the following example:

alist = [lambda : x for x in range(10) ]
print (alist[2]()) #9
print (alist[4]()) #9

The'll all be 9. Why? Because each lambda function refers to the variable x. x gets changed at every iteration through the loop, but they all still refer to the same object.

One way around this is to use a default argument. Default arguments are evaluated when the function is created, not when it is called.

alist = [lambda y=x: y for x in range(10) ]
print (alist[2]()) #2
print (alist[4]()) #4

(another way to do the same thing involves functools.partial which you'll see sometimes ...)

I often like to say -- "take care with closures". They can be a little tricky.



来源:https://stackoverflow.com/questions/11801121/python-tkinter-optionmenu-add-a-command-to-multiple-optionmenus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!