【问题标题】:Event binding arrow keys python Tkinter事件绑定箭头键 python Tkinter
【发布时间】:2014-03-26 00:20:16
【问题描述】:

我正在尝试在 tkinter 中制作一个简单的游戏,我需要将左/右箭头键绑定到一个类方法。该方法还接受一个参数。我已经完成了绑定,但是当我单击箭头键时,没有任何动作。我尝试向该方法添加一个打印语句,当我单击键时,没有打印任何内容,因此该方法没有被调用。我认为绑定不起作用,但我不知道如何修复它!

另外,如果用户持有绑定键,有没有办法继续运行绑定方法?就像单击并按住左键并让方法不断运行,直到用户放开为止。

谢谢。

from Tkinter import *
    from math import *
    global radius
    radius=175
    root=Tk()
    c=Canvas(root,width=600,height=600)
    c.pack()
    c.configure(scrollregion=(-300, -300, 300, 300))
    c.create_oval((-40,-40,40,40),fill="Yellow",outline="Yellow")
    def findcoords(angle,radius):
            #cos,sin
            a=cos(radians(angle))
            b=sin(radians(angle))
            return ((a*radius),(b*radius),(a*radius),(b*radius))

    def createOutline(radius):
        t=0
        while t<=360:
            c.create_rectangle(findcoords(t,radius))
            t+=.01
    class World():
        def __init__(self,canvas,img=None,size=20,angle=90):
            self.size=size
            self.angle=angle
            self.position=self.findcoord()
            self.canvas=canvas
            if img!=None:
                self.img=img
                self.current=c.create_image(self.position,image=self.img)
            else:
                self.current=c.create_oval(self.position,fill="Blue",outline="Blue")
            c.bind('<Left>',lambda event,arg=.1:self.move(event,arg))
            c.bind('<Right>',lambda event,arg=-.1:self.move(event,arg))
        def findcoord(self):
            #cos,sin
            a=cos(radians(self.angle))
            b=sin(radians(self.angle))
            return (((a*radius)-self.size),((b*radius)-self.size),((a*radius)+self.size),((b*radius)+self.size))           
        def move(self,n):
            self.angle+=.1
            self.position=self.findcoord()
            self.canvas.coords(self.current,self.position)

    createOutline(175)
    a=World(c)



    root.mainloop()

【问题讨论】:

    标签: python binding event-handling tkinter keyboard-events


    【解决方案1】:

    放弃类函数的 lambda。而不是

    lambda event,arg=.1:self.move(event,arg)
    
    lambda event,arg=-.1:self.move(event,arg))
    

    left
    

    right
    

    分别。一定要写对应的类函数和事件参数。

    我也不太明白你的代码。在move()(类World 的方法)中,您设置了参数n,但您从不使用它。试着清理一下你的代码,或者添加 cmets 来解释你到底在做什么。

    【讨论】:

      【解决方案2】:

      尝试使用以下方法设置焦点:

      c.focus_set()
      

      您也可以将密钥绑定到您的根目录

      root.bind('<Left>',lambda event,arg=.1:self.move(event,arg))
      root.bind('<Right>',lambda event,arg=-.1:self.move(event,arg))
      

      看起来您没有将注意力集中在框架上,因此键盘按键没有发送到正确的框架。

      只要保持状态,您就可以让事件继续进行,直到按键被释放。释放密钥的格式如下:

      c.bind("<KeyRelease-left>", onkeyrelease_of_key)
      

      将 onkeyrelease_of_key 替换为您的事件。

      【讨论】: