Tkinter带复选框下拉菜单问题:选中项后菜单自动折叠
解决Tkinter复选框下拉菜单多选时自动折叠的问题
你的问题是Tkinter原生Menubutton搭配Menu的复选框,点击选项后菜单会自动收起,无法连续多选。这是Tkinter菜单的默认行为,下面提供两种解决方案:
方法1:修改原生菜单,点击选项后重新展开
给每个复选框绑定命令,点击后重新显示菜单,同时调整按钮的点击逻辑来手动控制菜单的展开和折叠:
from tkinter import * def keep_menu_open(): # 重新在按钮下方显示菜单 main.menu.post(main.winfo_rootx(), main.winfo_rooty() + main.winfo_height()) root = Tk() main = Menubutton(root, text="Various Dates") main.pack() main.menu = Menu(main, tearoff=0) main['menu'] = main.menu Date0 = StringVar() Date1 = StringVar() Date2 = StringVar() Date3 = StringVar() # 为每个复选框添加命令,点击后重新打开菜单 main.menu.add_checkbutton(label='22/03/2024', variable=Date0, command=keep_menu_open) main.menu.add_checkbutton(label='24/03/2024', variable=Date1, command=keep_menu_open) main.menu.add_checkbutton(label='26/03/2024', variable=Date2, command=keep_menu_open) main.menu.add_checkbutton(label='28/03/2024', variable=Date3, command=keep_menu_open) # 绑定按钮点击事件,手动切换菜单的显示/隐藏 def toggle_menu(event): if main.menu.tk.call("tk::MenuExists", main.menu): main.menu.unpost() else: main.menu.post(main.winfo_rootx(), main.winfo_rooty() + main.winfo_height()) main.bind("<Button-1>", toggle_menu) root.mainloop()
方法2:自定义下拉面板(更稳定)
用Toplevel窗口模拟下拉菜单,完全控制显示逻辑,只有点击按钮才会折叠面板:
from tkinter import * root = Tk() class DropdownChecklist: def __init__(self, parent, btn_text, options): self.parent = parent self.options = options self.var_list = [] # 存储每个选项的状态变量 # 创建触发按钮 self.toggle_btn = Menubutton(parent, text=btn_text) self.toggle_btn.pack(pady=10) # 创建下拉面板 self.panel = Toplevel(parent) self.panel.withdraw() # 初始隐藏 self.panel.overrideredirect(True) # 去掉窗口标题栏和边框 self.panel.attributes("-topmost", True) # 始终在顶层 # 为每个选项添加复选框 for opt in options: var = StringVar() cb = Checkbutton(self.panel, text=opt, variable=var, padx=5, pady=2) cb.pack(anchor=W, fill=X) self.var_list.append(var) # 绑定按钮点击事件,切换面板显示/隐藏 self.toggle_btn.bind("<Button-1>", self.switch_panel) def switch_panel(self, event): if self.panel.state() == "normal": self.panel.withdraw() else: # 计算面板位置,放在按钮正下方 btn_x = self.toggle_btn.winfo_rootx() btn_y = self.toggle_btn.winfo_rooty() + self.toggle_btn.winfo_height() self.panel.geometry(f"+{btn_x}+{btn_y}") self.panel.deiconify() # 使用自定义下拉面板 date_options = ['22/03/2024', '24/03/2024', '26/03/2024', '28/03/2024'] date_dropdown = DropdownChecklist(root, "Various Dates", date_options) root.mainloop()
方法2的优势在于完全自定义行为,不会出现点击外部意外关闭的情况,更符合你的需求——只有点击按钮才折叠菜单。
内容的提问来源于stack exchange,提问作者Add
相关产品推荐
相关产品推荐

