You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:08:18