gpt4 book ai didi

Python Tkinter/如何让OptionMenus共享一项列表?

转载 作者:行者123 更新时间:2023-11-30 23:21:11 30 4
gpt4 key购买 nike

我正在尝试构建共享相同“基本项目列表”的多个选项菜单。不可能在不同菜单中多次选择一项,因此当在可用菜单之一中选择一项时,必须更新所有菜单。

from tkinter import *

# for example 5 fields
number_of_fields = 5
starting_list = ["item1","item2","item3","item4","item5"]
entry_list = []
option_list = []
option_var = []


def quit():
raise SystemExit()

# if an item is selected in one of the
# menus run this function
def reset_menu(sel_item):
# for each field
for field in range(number_of_fields):
new_list = []
selection = option_var[field].get()
# look for selected items in all menus
# and build new list which contains all
# items from the starting_list minus the
# items which are already selected
# keep the one selected (for a menu itself)
for option in starting_list:
marker = 0
for j in range(number_of_fields):
if(str(option_var[j].get()) == str(option)):
marker = 1
if(marker == 0):
new_list.append(str(option))
else:
pass
if(str(selection) == str(option)):
new_list.append(str(option))
# print new generated item list
# just to be sure it works so far
print("field",field,"new list=",new_list)

# NOW HERE SOMETHING IS WRONG I GUESS
# empty menu
option_list[field]["menu"].delete(0, "end")
# add new menu items
for item in new_list:
option_list[field]['menu'].add_command(label=item, command=lambda value=item:option_var[field].set(value))


root = Tk()
root.title("OptionMenu")

# menu variable for each field
for i in range(number_of_fields):
option_var.append(StringVar(root))

# initial value for each field
for i in range(number_of_fields):
option_var[i].set("")

# create menu for each field
for i in range(number_of_fields):
option_list.append(OptionMenu(root, option_var[i], *starting_list, command=reset_menu))

# create entry for each field
for i in range(number_of_fields):
entry_list.append(Entry(root))

# build gui
for i in range(number_of_fields):
entry_list[i].grid(row=int(i),column=0,sticky=N+S+W+E)
option_list[i].grid(row=int(i), column=1,sticky=N+S+W+E)
button = Button(root, text="OK", command=quit)
button.grid(row=number_of_fields,column=1,sticky=N+S+W+E)

mainloop()

现在一切似乎都很好,直到我尝试更新菜单。新的菜单项列表已正确生成(请参阅打印语句),并且菜单具有正确的项目,但在选择一个菜单后,唯一更改其选定状态的菜单是最后一个菜单。有什么想法吗?

问候现货

最佳答案

我发现你的问题是因为我也在尝试完成同样的任务。在 dir(tkinter) 中进行了一番探索后,我找到了一个解决方案,您启发了我创建一个帐户来发布。

我在代码中保留了您的原始评论,而我未更改的部分。

首先,用于生成选项的代码不必要地困惑。从完整列表中删除项目似乎更干净,而不是手动从空列表中填充列表。

您当前正在使用 tkinter.OptionMenu()。如果您改为使用 tkinter.ttk.OptionMenu(),它有一个名为 set_menu(*values) 的方法,该方法接受任意数量的值作为其参数,并将该菜单的选项设置为这些参数。

如果您进行切换,需要注意一件事 - ttk 的 OptionMenu 不允许在下拉列表中选择其默认值,因此建议将该值设为空白,就像我在starting_list 的声明中所做的那样。

为了保留空白选项,我添加了一个额外的空白选项,以便可以选择它。这样,如果您错误地选择了错误的选项,您可以恢复您的选择。

from tkinter import *
from tkinter.ttk import *

# for example 5 fields
number_of_fields = 5
starting_list = ["","item1","item2","item3","item4","item5"]
entry_list = []
option_list = []
option_var = []


def quit():
raise SystemExit()

# if an item is selected in one of the
# menus run this function
def reset_menu(sel_item):
# for each field
for field in range(number_of_fields):
new_list = [x for x in starting_list]
selection = option_var[field].get()
# look for selected items in all menus
# and build new list which contains all
# items from the starting_list minus the
# items which are already selected
# keep the one selected (for a menu itself)
for option in starting_list[1:6]:
#add selectable blank if option is selected
if (str(selection) == str(option)):
new_list.insert(0,"")
for j in range(number_of_fields):
if(str(selection) != str(option) and str(option_var[j].get()) == str(option)):
new_list.remove(option)
# print new generated item list
# just to be sure it works so far
print("field",field,"new list=",new_list)
#set new options
option_list[field].set_menu(*new_list)

root = Tk()
root.title("OptionMenu")

# menu variable for each field
for i in range(number_of_fields):
option_var.append(StringVar(root))

# initial value for each field
for i in range(number_of_fields):
option_var[i].set("")

# create menu for each field
for i in range(number_of_fields):
option_list.append(OptionMenu(root, option_var[i], *starting_list, command=reset_menu))

# create entry for each field
for i in range(number_of_fields):
entry_list.append(Entry(root))

# build gui
for i in range(number_of_fields):
entry_list[i].grid(row=int(i),column=0,sticky=N+S+W+E)
option_list[i].grid(row=int(i), column=1,sticky=N+S+W+E)
button = Button(root, text="OK", command=quit)
button.grid(row=number_of_fields,column=1,sticky=N+S+W+E)

mainloop()

您可能想要研究的是如何提高您的期权生成效率。现在,对于 n 个选项,您将循环菜单 n^2 次。我建议考虑传递刚刚在回调中选择的值,而不是搜索每个菜单以查看之前选择的内容。

作为一个额外的小注意事项,您的“确定”按钮会导致崩溃。我不确定这是故意行为、我的系统怪癖还是其他原因。

希望这会有所帮助!

关于Python Tkinter/如何让OptionMenus共享一项列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25066670/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com