根据另一个OptionMenu的选择更改OptionMenu选项

19

我目前正在尝试制作两个OptionMenu,第二个将根据第一个OptionMenu中选择的内容动态更新。

例如,我想要制作包含列表的OptionMenu_A

[North America, Europe, Asia]
  • 如果选择了 Asia,那么 OptionMenu_B 会变成类似于 [Japan, China, Malasia] 这样的东西。
  • 如果选择了 Europe,它就会变成类似于 [Germany, France, Switzerland] 的东西。

我能够创建两个 OptionMenu,但是无法根据 OptionMenu_A 的状态更新 OptionMenu_B

请问是否有人能够友好地展示一下是否可能实现这样的事情?

2个回答

27
是的,这是可能的。使用StringVar.trace,您可以检查何时更改了第一个选项。然后删除第二个OptionMenu的所有选项,并用相应的选项填充它。如果在此背后有像字典这样的数据结构,将相应关系映射起来就非常容易:
import sys
if sys.version_info[0] >= 3:
    import tkinter as tk
else:
    import Tkinter as tk


class App(tk.Frame):

    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.dict = {'Asia': ['Japan', 'China', 'Malaysia'],
                     'Europe': ['Germany', 'France', 'Switzerland']}

        self.variable_a = tk.StringVar(self)
        self.variable_b = tk.StringVar(self)

        self.variable_a.trace('w', self.update_options)

        self.optionmenu_a = tk.OptionMenu(self, self.variable_a, *self.dict.keys())
        self.optionmenu_b = tk.OptionMenu(self, self.variable_b, '')

        self.variable_a.set('Asia')

        self.optionmenu_a.pack()
        self.optionmenu_b.pack()
        self.pack()


    def update_options(self, *args):
        countries = self.dict[self.variable_a.get()]
        self.variable_b.set(countries[0])

        menu = self.optionmenu_b['menu']
        menu.delete(0, 'end')

        for country in countries:
            menu.add_command(label=country, command=lambda nation=country: self.variable_b.set(nation))


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    app.mainloop()

2
“self.variable_a.set('Asia')”命令是否会自动触发updateoptions(),以便设置self.optionmenu_b? - Tango

3

嗨,只是想补充一点。我成功地制作了3个动态选项菜单,其中两个是从前一个下拉菜单更新的...

from tkinter import *
root = Tk()

def update_options_B(*args):
    countries = data[variable_a.get()]
    variable_b.set(countries[0])
    menu = optionmenu_b['menu']
    menu.delete(0, 'end')
    for country in countries:
        menu.add_command(label=country, command=lambda nation=country: variable_b.set(nation))

def update_options_C(*args):
    cities = data2[variable_b.get()]
    variable_c.set(cities[0])
    menu = optionmenu_c['menu']
    menu.delete(0, "end")
    for city in cities:
        menu.add_command(label=city, command=lambda nation=city: variable_c.set(nation))


data = {'Asia': ['Japan', 'China', 'Malasia'],'Europe': ['Germany', 'France', 'Switzerland'], 'Africa': ['Nigeria', 'Kenya', 'Ethiopia']}
data2 = {'Japan': ["jiustu", "kamikaz", "Tokyo"], 'China': ["Shaigon", "Hong Kong"], 'Malasia': ["tiramusto", "quala lopour"], 'Germany': ["Dusseldorf", "Berlin", "Hambourg"], 'France': ["Paris", "Lille"], 'Switzerland': ["Biern", "Bonn"], 'Nigeria': ['Nigeria1', 'Nigeria3'], 'Kenya': ["Keny West", "Notorious"], 'Ethiopia': ["Etanpi", "Neeandertaal"]}
variable_a = StringVar()
variable_b = StringVar()
variable_c = StringVar()

variable_a.trace('w', update_options_B)
variable_b.trace('w', update_options_C)
optionmenu_a = OptionMenu(root, variable_a, *data.keys())
optionmenu_b = OptionMenu(root, variable_b, '')
optionmenu_c = OptionMenu(root, variable_c, '')

variable_a.set('Asia')
optionmenu_a.pack()
optionmenu_b.pack()
optionmenu_c.pack()


root.mainloop()

只是谢谢你 :) - Khushhal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接