Reputation: 367
I am trying to make a simple game in tkinter, and I need to bind the left/right arrow keys to a class method. The method also accepts an argument. I have done the binding, but when I click the arrow keys, nothing moves. I tried adding a print statement to the method, and when I click the keys, nothing prints, so the method isn't getting called. I don't think the binding is working, but I'm not sure how to fix it!
Also, is there a way to keep running a bound method if the user holds the bound key? Like click and holding the left key and having the method keep running over and over until the user lets go.
Thanks.
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()
Upvotes: 0
Views: 10216
Reputation: 21
Ditch the lambdas for class functions. Instead of
lambda event,arg=.1:self.move(event,arg)
lambda event,arg=-.1:self.move(event,arg))
do
left
and
right
respectively. Make sure to write corresponding class functions with the event parameter.
I also can't quite understand your code. In move()
(class World's method), you set the parameter n
, but you never use it. Try cleaning up your code a bit, or adding comments to explain what exactly you are doing.
Upvotes: 2
Reputation: 11
Try setting your focus using:
c.focus_set()
You could also bind the keys to your root so
root.bind('<Left>',lambda event,arg=.1:self.move(event,arg))
root.bind('<Right>',lambda event,arg=-.1:self.move(event,arg))
It's just looking like you don't have focus on the frame so the keyboard presses aren't getting sent to the correct frame.
As far as holding goes you can have the event continue until the key is released. Formatting for releasing keys goes like this:
c.bind("<KeyRelease-left>", onkeyrelease_of_key)
replacing the onkeyrelease_of_key with your event.
Upvotes: 1