在Tkinter中如何将一个被调用的函数作为参数传递?

3
在Tkinter中,使用<menu_item>.add_command()构建菜单栏时,需要为accelerator参数提供一个字符串,该字符串将创建命令的快捷键绑定。
我创建了一个方法,检查用户的平台是否为Mac或其他平台,如果是,则返回与其他键组合的Command键字符串。
但它不起作用->菜单正在构建中,如果我点击菜单项,它可以工作,但热键不能工作。尽管我可以在菜单中看到 + N
我的第一个想法是,传递作为参数时未调用self.hot_key()方法。
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()

1
就我个人而言,我从未使用过这个加速器。我通常只是使用self.gui.bind_all(...),但这可能会更加丑陋和不可靠。 - mgilson
事实证明,我必须使用bindbind_all将键盘事件绑定到一个方法上,accelerator只会在菜单中显示热键。所以你的版本并不丑陋或者是hacky,那是正确的做法。 - Peter Varo
好的,知道了。今天早上我学到了一些东西 :) - mgilson
1个回答

3
根据此页面
“accelerator”选项用于指示与此菜单关联的菜单加速器。这实际上并不创建加速器,但仅在菜单项旁边显示它是什么。您仍然需要自己为加速器创建绑定。
因此,您的关键字参数“accelerator”正在按设计工作-Command-N符号出现在您的菜单中。
正如mgilson在评论中建议的那样,您可以使用“bind_all”来使键盘组合实际起作用。
self.gui.bind_all("<Command-n>", lambda event: self.New())

好的,现在只有一件事我不明白:如果我使用bind或者bind_all,那么菜单就不会显示快捷键⌘ + N,即使它们已经在accelerator中定义了 - 这是为什么呢? - Peter Varo
这很不寻常。在我的机器上,使用Windows 7(并且用“Control”代替⌘)可以正常工作。也许这是一个特定于操作系统的问题? - Kevin
可能吧,但对我来说整个事情都太混乱了。我的意思是,如果add_command不能绑定键,为什么在其中有commandaccelerator参数呢?这很令人困惑,更不用说它在OS X菜单上显示不正确了:( - Peter Varo
1
@PeterVaro:加速器不为您绑定的原因是有多种方法可以进行绑定,tkinter 不知道您的意图。因此,您可以选择显示任何您想要的作为加速器,并且可以选择以任何您想要的方式进行绑定。加速器键和绑定之间并不总是直接的一对一映射,加速器中可见字符与实际绑定的按键也不总是直接的一对一映射关系。 - Bryan Oakley
@PeterVaro:你说如果使用bind,加速键就不会出现。这似乎非常不寻常。也许你可以创建一个非常小的程序来重现这个问题,然后发布一个单独的问题。 - Bryan Oakley
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接