Python Tkinter 级联菜单命令不执行

Cli*_*ock 5 python command cascade menu tkinter

我有一个问题,我正在尝试解决该问题,并使用下面的代码重现了该问题。

我遇到的问题是,我可以从主菜单项获取指定的命令,但是当级联菜单中包含相同的命令时,它似乎不会执行。

我不确定这是否与我的要求有关,我需要渲染按钮网格并为每个按钮附加一个上下文菜单。这是我设计的一些代码来演示这个问题:

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Tkinter Validation Demo')

        self.create_widgets()

    @staticmethod
    def print_bg_color(button, button_id):
        colour = button.cget('bg')
        print(f'Button {button_id} colour is {colour}')

    @staticmethod
    def _context_menu(event: tk.Event = None, menu: tk.Menu = None):
        menu.tk_popup(event.x_root, event.y_root)

    def create_widgets(self):
        colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
        for i in range(0, 7):
            button = tk.Button(master=self, bg=colors[i], width=10, height=10)
            button.grid(row=0, column=i)
            context_menu = tk.Menu(button, tearoff=False)
            # Add print option to main menu
            context_menu.add_command(label="Print colour",
                                     command=lambda btn=button, button_id=i:
                                     self.print_bg_color(button=btn, button_id=button_id))

            sub_menu = tk.Menu(button, tearoff=False)
            # Add a print colour option on the sub menu
            sub_menu.add_command(label="Print colour",
                                 command=lambda btn=button, button_id=i:
                                 self.print_bg_color(button=btn, button_id=button_id))
            context_menu.add_cascade(label='Cascade', menu=sub_menu)

            button.bind("<Button-3>",
                        lambda event, menu=context_menu, button_id=i:
                        self._context_menu(event, menu))


if __name__ == '__main__':
    app = App()
    app.mainloop()
Run Code Online (Sandbox Code Playgroud)

运行上述代码时,它允许您右键单击任何呈现的按钮,然后从主上下文菜单或级联选项中选择“打印颜色”。绑定到事件的命令只是获取按钮的颜色并将其打印到控制台。这适用于主上下文菜单选项,但级联菜单条目不执行任何操作,尽管具有相同的命令。

任何建议都非常感激。

谢谢。

更新:确定这似乎只发生在运行 Python 3.8 的 Linux Mint 环境上(它可以在使用 Python 3.10 的 Windows 10 上运行),我运行了 Nordine 在评论中建议的脚本:

import tkinter
from platform import python_version
print(python_version())
root = tkinter.Tk()
print(root.tk.call("info", "patchlevel"))
Run Code Online (Sandbox Code Playgroud)

结果显示为:

3.8.10
8.6.10

进一步更新:

我刚刚在我的 Linux Mint 机器上升级到 Python 3.10,但它仍然无法工作:o/

Mar*_*ijn 1

问题代码中的子菜单设置为以下元素button

sub_menu = tk.Menu(button, tearoff=False)
Run Code Online (Sandbox Code Playgroud)

但是,这会导致子菜单正确显示但不可单击(在 Ubuntu、Python 3.10.6、Tkinter 8.6 上重现)。当您将子菜单作为其中的一个元素时,context_menu它就可以工作:

sub_menu = tk.Menu(context_menu, tearoff=False)
Run Code Online (Sandbox Code Playgroud)