Is there a way to bind functionality to tkinter menu items without using command= option

72 Views Asked by At

Lets assume i have an simple list as follow:

import tkinter as tk

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

menubar = tk.Menu(root)
menu1 = tk.Menu(menubar, tearoff=0)
menu1.add_command(label="Button1")
menu1.add_command(label="Button2")
menubar.add_cascade(label='Menu1', menu=menu1)

tk.Tk.config(root, menu=menubar)

root.mainloop()

Can i add two different functionalities to Button1 and Button2 that are triggered when they are clicked on without using menu1.add_command(label="Button1", command=func1) and menu1.add_command(label="Button2", command=func2)?

Preferably, I am looking for some solution somehow doing something like these hypothetical solutions:

def func1():
    pass
def func2():
    pass
def binding(Menu1):
    Menu1.Button1.bind(func1)
    Menu1.Button2.bind(func2)

or

def handler(event):
    if event = button1:
        func1()
    if event = button2:
        func2()

menu1.bind(<clicked>, handler)
3

There are 3 best solutions below

1
acw1668 On BEST ANSWER

You can use the label of the menu item to get the index of it in the menu and then use menu1.entryconfig() to bind a function on that menu item:

def binding(menu, label, func):
    for i in range(menu.index("end")+1):
        if menu.entrycget(i, "label") == label:
            menu.entryconfigure(i, command=func)
            return

binding(menu1, "Button1", func1)
binding(menu1, "Button2", func2)
1
sgrenz On

Why would you want to do it like this, you can just declare the button with the function inside. You could make them execute a function with different values like :

Button1 = tk.Button(command = lambda : func(1))
Button2 = tk.Button(command = lambda : func(2))



func(x):
  if(x == 1):
    func1()
  if(x == 2):
    func2()
0
Ovski On

I'm not sure if changing the command after adding an item to the menu is possible. You can delete one and add a new one.

menu1.delete('Button2')

But in reply to your comment that you want to define the menu items in another module. You can pass menu1 as an argument to your module and add items there. See this example with a class "OtherModule"

import tkinter as tk


class OtherModule:
    def __init__(self, menu):
        menu.add_command(label='another menu', command=self.another_menu)

    def another_menu(self):
        print('another menu item')


def button1():
    print('button1')


def button2():
    print('button2')


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

menubar = tk.Menu(root)
menu1 = tk.Menu(menubar, tearoff=0)
menu1.add_command(label="Button1", command=button1)
menu1.add_command(label="Button2", command=button2)
menubar.add_cascade(label='Menu1', menu=menu1)
tk.Tk.config(root, menu=menubar)


other_module = OtherModule(menu1)
root.mainloop()