Tkinter多级下拉菜单选中选项后如何更新菜单按钮文本?
Tkinter多级下拉菜单选中选项后如何更新菜单按钮文本?
嘿,我完全懂你踩的这个坑!你用递归生成多级菜单的时候,直接给add_cascade绑定command=self.func(category)会触发一个典型的问题:这个函数会在循环创建菜单的瞬间就立刻执行,而不是等你点击菜单项的时候才触发——这就是为什么按钮一启动就直接显示最后一个分类"G"的原因。
另外还有个小细节要纠正:没有子分类的叶子节点,不该用add_cascade(它是用来挂载子菜单的),这类选项应该用add_command来绑定点击事件才对。
我给你调整了代码,主要解决这两个问题:
- 用
lambda延迟函数执行,并且通过默认参数保存循环中的每个分类值,避免循环变量的引用陷阱 - 叶子节点改用
add_command,有子分类的父菜单不用加command(它只负责展开子菜单,不需要触发文本更新)
修改后的完整代码如下:
import tkinter as tk from tkinter import ttk class Window: def __init__(self, master): self.categories = { "A": { "B": { "C": {}, "D": {}, }, "E": { "F": {} } }, "G": {} } self.menu_button = ttk.Menubutton(master, text="Select") self.top_menu = tk.Menu(self.menu_button, tearoff=False) self.menu_button.configure(menu=self.top_menu) self.create_category_menu(self.categories, self.top_menu) self.menu_button.pack() # 递归创建菜单的函数 def create_category_menu(self, categories, top_menu): for category in categories: if len(categories[category]) == 0: # 叶子节点:用add_command绑定点击事件,lambda默认参数保存当前category top_menu.add_command( label=category, command=lambda cat=category: self.update_button_text(cat) ) else: # 有子分类的父菜单:只创建子菜单,无需绑定command sub_menu = tk.Menu(top_menu, tearoff=False) top_menu.add_cascade(label=category, menu=sub_menu) self.create_category_menu(categories[category], sub_menu) # 更新按钮文本的函数 def update_button_text(self, category): self.menu_button["text"] = category root = tk.Tk() window = Window(root) root.mainloop()
现在你点击任何叶子节点(比如C、D、F、G),菜单按钮的文本就会立刻变成你选中的选项啦!
备注:内容来源于stack exchange,提问作者Tolga
相关产品推荐
相关产品推荐

