Tkinter多级下拉菜单故障:选Plot和Cluster后无楼层选项
问题原因
你在更新子区域菜单时,仅用tk._setit更新了sub_area_var变量,但没有绑定触发update_level_menu的逻辑。也就是说,当用户选择子区域时,只会更新下拉框显示的文本,不会调用更新楼层菜单的方法,所以楼层选项不会生成。
修复方案
修改update_sub_area_menu方法中添加菜单命令的代码,用lambda同时实现变量更新和触发update_level_menu。另外注意Hotel-Ultra Luxury里的"52"应该改为"52F",避免后续匹配错误。
修复后的完整代码
import tkinter as tk class App: def __init__(self, master): self.master = master self.master.geometry("300x200") self.master.title("Document Finder") # Create dropdown menus self.location_var = tk.StringVar() self.location_var.set("Select the Plot") self.location_dropdown = tk.OptionMenu(self.master, self.location_var, "Plot A", "Plot B",command = self.update_sub_area_menu) self.location_dropdown.pack() self.sub_area_var = tk.StringVar() self.sub_area_var.set("Select the sub-area") self.sub_area_dropdown = tk.OptionMenu(self.master, self.sub_area_var,"",command = self.update_level_menu) self.sub_area_dropdown.pack() self.level_var = tk.StringVar() self.level_var.set("Select a level") self.level_dropdown = tk.OptionMenu(self.master, self.level_var,"",command=self.update_room_menu) self.level_dropdown.pack() self.room_var = tk.StringVar() self.room_var.set("Select a room") self.room_dropdown = tk.OptionMenu(self.master, self.room_var,"") self.room_dropdown.pack() # Create button to search for document self.search_button = tk.Button(self.master, text="Submit") self.search_button.pack() def update_sub_area_menu(self,selection): if selection == "Plot A": sub_areas = ["Basement A", "Club Lounge", "Hotel-Luxury", "Hotel-Service Apartments", "Hotel-Ultra Luxury", "Link Levels", "Others", "Penthouses", "Podium A", "Rental Offices", "Restaurants", "Spa/Gym"] elif selection == "Plot B": sub_areas = ["Apartments-Duplex", "Apartments-Simplex", "Basement B", "Link", "Mech & Roof", "Podium B"] else: sub_areas = [] self.sub_area_var.set("Select the sub-area") self.sub_area_dropdown['menu'].delete(0, 'end') for sub_area in sub_areas: # 修改这里,用lambda同时更新变量并触发update_level_menu self.sub_area_dropdown['menu'].add_command( label=sub_area, command=lambda sa=sub_area: [self.sub_area_var.set(sa), self.update_level_menu(sa)] ) def update_level_menu(self, selection): if selection == "Basement A": levels = ["B1", "B2", "B3", "B4", "B5", "B6", "B7"] elif selection == "Club Lounge": levels = ["53F"] elif selection == "Hotel-Luxury": levels = ["30F", "31F", "32F", "33F", "34F", "35F", "36F", "37F", "38F", "39F", "40F", "41F", "42F", "43F", "44F"] elif selection == "Hotel-Service Apartments": levels = ["54F", "55F", "56F", "57F", "58F", "59F", "60F"] elif selection == "Hotel-Ultra Luxury": # 修正这里的"52"为"52F" levels = ["46F", "47F", "48F", "49F","50F", "51F", "52F"] elif selection == "Link Levels": levels = ["23F", "24F", "25F", "26F"] elif selection == "Others": levels = ["22F", "23F", "29F", "45F", "67F", "RF", "RF"] elif selection == "Penthouses": levels = ["61F", "62F", "63F", "64F", "65F", "66F"] elif selection == "Podium A": levels = ['GF', "1F", "2F","3F"] elif selection == "Rental Offices": levels = ["5F", "6F", "7F", "8F", "9F", "10F", "11F", "12F", "13F", "14F", "15F","16F","17F","18F","19F","20F","21F"] elif selection == "Restaurants": levels = ["4F"] elif selection == "Spa/Gym": levels = ["27F", "28F"] elif selection == "Apartments-Duplex": levels = ["30F", "31F", "32F", "33F", "34F", "35F", "36F", "37F", "38F", "39F", "40F", "41F", "42F", "43F", "44F", "45", "46F", "47F", "48F", "49F","50F", "51F", "52F", "53F", "54F","55F", "56F","57F","58F"] elif selection == "Apartments-Simplex": levels = ["5F", "6F", "7F", "8F", "9F","10F","11F","12F","13F","14F","15F","16F","17F","18F","19F","20F","21F","22F","23F","24F","25F","26F"] elif selection == "Basement B": levels = ["B1","B2","B3","B4","B5","B6","B7"] elif selection == "Link": levels = ["28F", "29F"] elif selection == "Mech & Roof": levels = ["RF"] elif selection == "Podium B": levels = ["GF","1F","2F","4F"] else: levels = [] self.level_var.set("Select a level") # 重置楼层选择提示 self.level_dropdown['menu'].delete(0, 'end') for level in levels: self.level_dropdown['menu'].add_command( label=level, command=lambda l=level: [self.level_var.set(l), self.update_room_menu(l)] ) def update_room_menu(self, selection): if selection == "B1": rooms = ["FWT BA 001","FWT BA 002","RAMP 1 BA 003","MECH WATER TANK (WATER FEATURE 13) BA 004"] else: rooms = [] self.room_var.set("Select the room") self.room_dropdown['menu'].delete(0, 'end') for room in rooms: self.room_dropdown['menu'].add_command(label=room, command=tk._setit(self.room_var, room)) root = tk.Tk() app = App(root) root.mainloop()
额外优化说明
- 在
update_level_menu中添加了self.level_var.set("Select a level"),每次切换子区域时重置楼层选择的提示文本,体验更友好 - 修正了
Hotel-Ultra Luxury中的楼层拼写错误,避免后续选择时无法匹配到正确的楼层列表
内容的提问来源于stack exchange,提问作者hexapod
相关产品推荐
相关产品推荐

