在一个TKinter con中有多个事件

2024-04-20 00:14:12 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑以下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\u something”将立即执行。到现在为止,一直都还不错。你知道吗

现在我希望每次用户单击选项菜单时都刷新选项列表:

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()

每次单击控件时都会执行“刷新选项列表”,并向列表中添加另一个选项。这很好。但不再起作用的是“do\u something”命令,它不再执行了。我做错什么了?你知道吗


Tags: newgetmydefrootdowinsomething
1条回答
网友
1楼 · 发布于 2024-04-20 00:14:12

当您添加新选项时,您将擦除整个菜单并重新构建它。这没关系,但问题是您还重置了所有菜单元素的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(),并将它所属的选项传递给它。您应该注意^{} 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)行,只需在do_something()末尾添加对refresh_option_list()的调用,但这取决于您试图有效实现的目标,因此这可能不是您需要的。你知道吗

相关问题 更多 >