考虑以下最小的TKinter应用程序:
import tkinter as tki
def do_something(*args):
print('{} selected'.format(my_choice.get()))
root_win = tki.Tk()
option_list = ['apple', 'orange']
my_choice = tki.StringVar()
my_choice.set('-- nothing selected --')
script_list = tki.OptionMenu(root_win, my_choice,
command=do_something,
*option_list)
script_list.pack(padx=20, pady=20)
root_win.mainloop()
用户一旦选择,便会初始化OptionMenu并执行“ do_something”。到目前为止,一切都很好。
现在,我希望每次用户单击OptionMenu时刷新选项列表:
import tkinter as tki
from random import randrange
def do_something(*args):
print('{} selected'.format(my_choice.get()))
fruit = ['strawberry', 'banana', 'pineapple']
def get_new_choice():
if len(fruit) > 0:
new_fruit = fruit[randrange(len(fruit))]
fruit.remove(new_fruit)
return new_fruit
else:
return 'no more fruit'
def refresh_option_list(*args):
option_list.append(get_new_choice())
my_menu = my_om['menu']
my_menu.delete(0, "end")
for option in option_list:
my_menu.add_command(label=option, command = '')
root_win = tki.Tk()
option_list = ['apple', 'orange']
my_choice = tki.StringVar()
my_choice.set('-- nothing selected --')
my_om = tki.OptionMenu(root_win, my_choice,
command=do_something,
*option_list)
my_om.bind('<Button-1>', refresh_option_list)
my_om.pack(padx=20, pady=20)
root_win.mainloop()
每次单击控制按钮时都会执行“ refresh_option_list”,并将另一个选项添加到列表中。很好但是,不再起作用的是“ do_something”命令,该命令不再执行。我究竟做错了什么?
最佳答案
添加新选项时,将擦除整个菜单并重新构建。没关系,但是问题在于您还要重置所有菜单元素的command
选项,因此它们停止运行do_something()
函数,并失去与my_choice
变量的连接。
您可以尝试的一种方法是在添加新选项时执行此操作:
for option in option_list:
my_menu.add_command(label=option, command=lambda o=option: do_something(o))
这意味着您将所有选项连接到
do_something()
,并将其传递给哪个选项。您应该注意使用lambda
function。然后,稍微改变
do_something()
来模拟与my_choice
变量的连接:def do_something(option):
my_choice.set(option)
print('{} selected'.format(my_choice.get()))
我想做的另一件事是删除
my_om.bind('<Button-1>', refresh_option_list)
行,并简单地在refresh_option_list()
的末尾添加对do_something()
的调用,但这取决于您要有效实现的目标,因此并非您所需要的。