【问题标题】:Tkinter - Can't bind arrow key eventsTkinter - 无法绑定箭头键事件
【发布时间】:2013-11-10 22:11:00
【问题描述】:

我正在尝试将左右箭​​头键绑定到 Tkinter 中的事件,但是当我运行程序时,似乎事件没有触发。代码如下:

from Tkinter import *

main = Tk()

def leftKey(event):
    print "Left key pressed"

def rightKey(event):
    print "Right key pressed"

frame = Frame(main, width=100, height=100)
frame.bind('<Left>', leftKey)
frame.bind('<Right>', rightKey)
frame.pack()
frame.mainloop()

为什么这不起作用?

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    尝试绑定到你的主变量:

    from Tkinter import *
    
    main = Tk()
    
    def leftKey(event):
        print "Left key pressed"
    
    def rightKey(event):
        print "Right key pressed"
    
    frame = Frame(main, width=100, height=100)
    main.bind('<Left>', leftKey)
    main.bind('<Right>', rightKey)
    frame.pack()
    main.mainloop()
    

    我应该解释这是因为 Tk 知道绑定,因为主窗口具有键盘焦点。正如@BryanOakley 的回答所解释的,您也可以将键盘焦点设置到另一帧:

    from Tkinter import *
    
    main = Tk()
    
    def leftKey(event):
        print "Left key pressed"
    
    def rightKey(event):
        print "Right key pressed"
    
    frame = Frame(main, width=100, height=100)
    frame.bind('<Left>', leftKey)
    frame.bind('<Right>', rightKey)
    frame.focus_set()
    frame.pack()
    main.mainloop()
    

    查看更多关于events and bindings at effbot的信息。

    此外,您还可以重写此代码,使您的应用程序成为 Tkinter.Frame 的子类,如下所示:

    import Tkinter
    
    
    class Application(Tkinter.Frame):
        def __init__(self, master):
            Tkinter.Frame.__init__(self, master)
            self.master.minsize(width=100, height=100)
            self.master.config()
    
            self.master.bind('<Left>', self.left_key)
            self.master.bind('<Right>', self.right_key)
    
            self.main_frame = Tkinter.Frame()
            self.main_frame.pack(fill='both', expand=True)
            self.pack()
    
        @staticmethod
        def left_key(event):
            print event + " key pressed"
    
        @staticmethod
        def right_key(event):
            print event + " key pressed"
    
    root = Tkinter.Tk()
    app = Application(root)
    app.mainloop()
    

    【讨论】:

    • 太好了,很高兴为您提供帮助!我已经使用应用程序的 Frame 子类更新了答案。编码愉快!
    • 实际问题只是框架没有键盘焦点。如果您将焦点设置为框架,问题中的代码将正常工作。
    • @BryanOakley 谢谢,我会用这个替代解决方案更新答案。
    • 要记住的重要一点是将键绑定到根框架/窗口,而不是任何嵌套框架(也不是显示快捷方式的小部件)。
    【解决方案2】:

    问题只是您绑定到的框架没有键盘焦点。当您按下键盘上的某个键时,该事件将发送到具有键盘焦点的小部件。默认情况下,框架没有键盘焦点。

    将以下行添加到您的代码中以将键盘焦点移动到框架:

    frame.focus_set()
    

    【讨论】:

    • +1 好点,我已更新答案以包含此解决方案。
    • 如果小部件没有监听器,具有焦点的小部件的父级是否会获取事件?
    • @MadPhysicist:不。 this answer 描述了会发生什么。
    【解决方案3】:
    from tkinter import *
    
    
    def leftKey(event):
        print("Left key pressed")
    
    
    def rightKey(event):
        print("Right key pressed")
    
    
    main = Tk()
    
    
    frame = Frame(main, width=100, height=100)
    main.bind('<Left>', leftKey)
    main.bind('<Right>', rightKey)
    frame.pack()
    main.mainloop()
    

    【讨论】:

    • 我看不出你的回答对 Fiver 的旧答案有什么影响。
    • 它添加了我需要的括号
    • 这个答案与 Fiver 的答案完全相同,只是这仅适用于 python 3。但是 OP 使用的是 python 2,所以 from tkinter import * 不起作用,括号也没有任何区别。
    • @abccd 我需要括号。
    【解决方案4】:

    可能是您没有拦截正确的事件。数字小键盘上的箭头和其他箭头有不同的符号名称。

    http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/key-names.html

    数字小键盘上的名称前面带有“KP_”。

    希望对您有所帮助。如果不相关,请原谅新手:-)

    【讨论】: