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

Tkinter多选下拉菜单点击选项后自动收回,如何让菜单保持打开?

解决Tkinter多选下拉菜单选中后自动收回的问题

要让Tkinter的多选下拉菜单保持打开状态,直到点击外部区域或再次点击按钮,你需要在选中选项后重新弹出菜单,并添加点击外部关闭的逻辑。以下是修改后的代码:

import tkinter as tk

def update_selected_options(option, var, selected_options):
    if var.get():
        if option not in selected_options:  # 避免重复添加选项
            selected_options.append(option)
    else:
        if option in selected_options:
            selected_options.remove(option)
    print(selected_options)

def select_option(option, var, selected_options, menu, menubutton):
    update_selected_options(option, var, selected_options)
    # 重新弹出菜单,保持打开状态
    x = menubutton.winfo_rootx()
    y = menubutton.winfo_rooty() + menubutton.winfo_height()
    menu.post(x, y)

def create_dropdown(parent, options):
    selected_options = []
    menu_open = tk.BooleanVar(value=False)

    # 创建Menubutton
    menubutton = tk.Menubutton(parent, text="Choose options", indicatoron=True, borderwidth=1, relief="raised")
    menu = tk.Menu(menubutton, tearoff=False)  # 关闭可拖拽功能,更贴合多选菜单场景
    menubutton.configure(menu=menu)
    menubutton.pack(padx=10, pady=10)

    # 添加多选按钮
    for option in options:
        var = tk.BooleanVar(value=False)
        # 传入菜单和按钮对象,用于选中后重新弹出菜单
        menu.add_checkbutton(
            label=option,
            variable=var,
            onvalue=True,
            offvalue=False,
            command=lambda option=option, var=var: select_option(option, var, selected_options, menu, menubutton)
        )

    # 点击按钮切换菜单显示/隐藏状态
    def toggle_menu(event):
        if menu_open.get():
            menu.unpost()
            menu_open.set(False)
        else:
            x = menubutton.winfo_rootx()
            y = menubutton.winfo_rooty() + menubutton.winfo_height()
            menu.post(x, y)
            menu_open.set(True)

    menubutton.bind("<Button-1>", toggle_menu)

    # 点击窗口其他区域时关闭菜单
    def close_menu_on_click(event):
        if menu_open.get() and not menubutton.winfo_containing(event.x_root, event.y_root):
            menu.unpost()
            menu_open.set(False)

    parent.bind("<Button-1>", close_menu_on_click)

    return menubutton

if __name__ == "__main__":
    root = tk.Tk()
    options = ["Option 1", "Option 2", "Option 3"]
    menubutton = create_dropdown(root, options)
    root.mainloop()

关键修改说明:

  • 重新弹出菜单:在选中选项的回调函数中,获取按钮的屏幕坐标,调用menu.post()重新弹出菜单,解决选中后菜单自动收回的问题。
  • 菜单状态管理:用menu_open变量跟踪菜单的打开状态,配合按钮的点击事件实现菜单的显示/隐藏切换。
  • 外部点击关闭:绑定窗口的点击事件,判断点击位置是否在按钮区域外,若是则关闭菜单。
  • 列表操作优化:在更新选中列表时增加存在性判断,避免重复添加或删除选项导致的错误。

内容的提问来源于stack exchange,提问作者Warehouse_Worker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:22:43