如何在 tkinter 菜单中自动打开子菜单?

How do you open a submenu automatically in a tkinter menu?

我知道 menu.tk_popup() 可用于在特定坐标处打开上下文菜单,但也不知道如何从中打开子菜单,如果这有意义的话。这是我编写的代码:

import tkinter as tk

root = tk.Tk()
root.geometry("500x400")

def contextMenu(e, openCascade=False):
    my_menu2 = tk.Menu(root, tearoff=False)
    my_menu2.add_command(label="command2")
    my_menu = tk.Menu(root, tearoff=False)
    my_menu.add_cascade(label="cascade1", menu=my_menu2)
    my_menu.add_command(label="command1")
    my_menu.tk_popup(e.x_root, e.y_root)
    if openCascade:
        my_menu2.tk_popup(e.x_root, e.y_root) #doesn't work

root.bind("<Button-3>", contextMenu)
root.bind("<Button-2>", lambda e: contextMenu(e=e, openCascade=True))

root.mainloop()

代码基本上是 window,当右键单击(< Button-3> 绑定)时,将显示第一个菜单 (my_menu),其中有一个级联 (cascade1),手动时运行(即单击),显示子菜单 (my_menu2),如下所示。

问题不在于右键单击,而是中键单击(< Button-2> 绑定)无法按我的预期工作。当我单击鼠标中键时,我试图让它显示两个菜单(my_menu、my_menu2),但我的尝试只显示两个菜单,但第一个菜单重叠,所以另一个不t显示。

那么问题来了,我该如何做到在点击鼠标中键时打开第一个菜单然后自动运行级联,就好像它被点击了一样?如果您不明白我解释的内容,请不要犹豫。

So the question is, how do I make it so when middle-clicking, it opens the first menu AND then automatically runs the cascade, as if it was clicked?

考虑到 this answer by Bryan Oakley 和 Internet 上可用的文档,无法同时显示菜单和子菜单。 “这不是 Tkinter 菜单设计的工作方式。”

您必须在不使用小部件的情况下创建自定义菜单栏 tk.Menu


When I middle-click, I tried to make it so it displays both the menus (my_menu, my_menu2), but my attempt just displays both but with the first menu overlapping, so the other doesn't show.

它们不重叠。即使您使用一些整数为 x-y 值添加一些间隙,您仍然不会看到第二个菜单。

原因是使用tk_popuppost肯定会使菜单出现在屏幕上,但程序的焦点会转移到用户的鼠标和键盘上。因此,直到用户单击该菜单的焦点之外,程序才会出来执行函数的下一行(您在其中为子菜单调用 tk_popup。)

这里你可以明白我的意思了:

    .
    .
    .
    my_menu.add_command(label="command1")
    
    print("Before my_menu popup")
    my_menu.tk_popup(e.x_root, e.y_root)
    print("After my_menu popup")
    if openCascade:
        print("Before my_menu2 popup")
        my_menu2.tk_popup(e.x_root+30, e.y_root+50) #added some gap to show they are not overlapping
        print("After my_menu2 popup")

root.bind("<Button-3>", contextMenu)
root.bind("<Button-2>", lambda e: contextMenu(e,True))

root.mainloop()

因此,当您 middle-clicking (< Button-2> 绑定) 时,输出为:

Before my_menu popup

my_menu 在屏幕上可见。 然后,当用户点击该菜单的焦点之外时,my_menu 消失,您将获得以下输出:

After my_menu popup
Before my_menu2 popup
After my_menu2 popup

子菜单出现在屏幕上,但由于点击退出,新的焦点在根上,子菜单不到一秒就消失了。