Peter Varo
Peter Varo

Reputation: 12180

In Tkinter how to pass a called function as argument?

In Tkinter for constructing the menubar with the <menu_item>.add_command() we need a string for the accelerator argument which will create the hotkey binding for a command.

I created a method, which is checking if the user's platform is Mac or other, and if it is, then returns the Command key string combined with the other keys.

But it doesn't work -> the menu is building, if I click on the menu-item it is working, but not working with the hot-keys. ALthough I can see the + N in the menu..

My first thought is, that the self.hot_key() method is not called while passed as an argument..

import sys
import Tkinter

class app(object):

    def __init__(self):
        self.gui = Tkinter.Tk()
        self.gui.minsize(width=640, height=320)
        menu = Tkinter.Menu(self.gui)
        filemenu = Tkinter.Menu(menu, tearoff=0)
        filemenu.add_command(
            label       = 'New',
            command     = self.New,
            accelerator = self.hot_key('n')
        )
        menu.add_cascade(
            label = 'File',
            menu  = filemenu
        )
        self.gui.config(menu=menu)

        self.text = Tkinter.Text(self.gui)
        self.text.pack(expand=Tkinter.YES, fill=Tkinter.BOTH)

    def hot_key(self, *keys):
        super_key = 'Command' if sys.platform == 'darwin' else 'Control'
        return '{super}+{keys}'.format(super=super_key, keys='+'.join(keys))

    def New(self):
        print "I'm working!"

App = app()
App.gui.mainloop()

Upvotes: 3

Views: 347

Answers (1)

Kevin
Kevin

Reputation: 76254

According to this page,

The "accelerator" option is used to indicate the menu accelerator that should be associated with this menu. This does not actually create the accelerator, but only displays what it is next to the menu item. You still need to create a binding for the accelerator yourself.

So your accelerator keyword argument is working as designed -- the Command-N symbol appears in your menu.

As mgilson suggests in a comment, you can use bind_all to get the keyboard combination to actually do something.

self.gui.bind_all("<Command-n>", lambda event: self.New())

Upvotes: 3

Related Questions