簡體   English   中英

一個TKinter控件中有多個事件

[英]Multiple events in one TKinter control

考慮以下最小的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函數

然后,您需要稍微更改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()的調用,但這取決於什么您正在嘗試有效地實現目標,因此這可能不是您所需要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM