Tkinter obteniendo la tecla presionada evento de una función

Tengo el siguiente código,

Si presiono ‘Tecla de flecha izquierda’, solo se imprime move player to left Pero necesito una funcionalidad en la que al presionar la tecla de flecha dada se mueve al jugador en la dirección dada.

¿Hay alguna forma en la que pueda detectar eventos de pulsación de tecla en mi función move_dir
PD: bastante nuevo para python

 import Tkinter as tk move = 1 pos = -1 def move_dir(): global move global pos while move ==1: if pos == 0: print 'move player to left' elif pos == 1: print 'move player to right' elif pos == -1: print 'stop moving!' def kr(event): global move global pos global root if event.keysym == 'Right': move = 1 pos = 0 move_dir() print 'right ended' elif event.keysym == 'Left': move = 1 pos = 1 move_dir() print 'left ended' elif event.keysym == 'Space': move = 0 move_dir() elif event.keysym == 'Escape': root.destroy() root = tk.Tk() print( "Press arrow key (Escape key to exit):" ) root.bind_all('', kr) root.mainloop() 

EDITAR 4

Tiene un bucle while que desea combinar con el mainkop Tkinter. En este caso, desea moverse cuando se presiona la tecla y dejar de moverse cuando se suelta una tecla. El siguiente código le permite hacer esto:

 import Tkinter as tk from guiLoop import guiLoop # https://gist.github.com/niccokunzmann/8673951#file-guiloop-py direction = 0 pos = 0 # the position should increase and decrease depending on left and right # I assume pos can be ... -3 -2 -1 0 1 2 3 ... @guiLoop def move_dir(): global pos while True: # edit 1: now looping always print 'moving', direction pos = pos + direction yield 0.5 # move once every 0.5 seconds def kp(event): global direction # edit 2 if event.keysym == 'Right': direction = 1 # right is positive elif event.keysym == 'Left': direction = -1 elif event.keysym == 'Space': direction = 0 # 0 is do not move elif event.keysym == 'Escape': root.destroy() def kr(event): global direction direction = 0 root = tk.Tk() print( "Press arrow key (Escape key to exit):" ) root.bind_all('', kp) root.bind_all('', kr) move_dir(root) root.mainloop() 

Para ver cómo se implementa esto, puede leer el código fuente o leer la segunda respuesta de Bryan Oakley.

EDITAR 3

No hay manera de detectar una pulsación de tecla en la función move_dir directamente. Puede usar root.update() en su función move_dir para hacer posible que kr , kp se ejecute cuando se root.update . root.update() vuelve a pintar las ventanas para que el usuario pueda ver los cambios.

root.mainloop() puede verse como while True: root.update()

Si desea animar algo, debe usarlo after para configurar un ciclo de animación. Un bucle de animación se ve así:

 def animate():  after(, animate) 

Puedes poner cualquier código que quieras para dibujar un marco. En tu caso, parece que quieres mover algo a la izquierda o la derecha. El parámetro define su velocidad de fotogtwigs. Por ejemplo, para obtener 30FPS, su retraso sería de aproximadamente 33 (1000ms / 30). Lo único importante a tener en cuenta es que debe ejecutarse con bastante rapidez (10 milisegundos o menos) para no bloquear la GUI.

Para su problema en particular, puede configurar una variable para definir la dirección cuando el usuario presiona una tecla, y luego desactivar la variable cuando suelta la tecla. El controlador de eventos y la función animada podrían tener un aspecto similar al siguiente:

 def animate(): if direction is not None: print "move player to the ", direction after(33, animate) def on_keypress(event): global direction if event.keysym == "Left": direction = "left" elif event.keysum == "right": direction = "right" def on_keyrelease(event): global direction direction = None 

¿Ves cómo funciona eso? Al pulsar una tecla se define la dirección. Luego, cada 33 milisegundos verifica la dirección y mueva a su jugador si la dirección está definida. Cuando el usuario suelta el botón, la dirección se vuelve indefinida y el movimiento se detiene.

Poniéndolo todo junto, y usando una clase para evitar el uso de variables globales, se parece a lo siguiente. Esto crea una bola en un canvas que puedes mover hacia la izquierda, derecha, arriba y abajo:

 import Tkinter as tk class Example(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.direction = None self.canvas = tk.Canvas(width=400, height=400) self.canvas.pack(fill="both", expand=True) self.canvas.create_oval(190, 190, 210, 210, tags=("ball",), outline="red", fill="red") self.canvas.bind("", self.on_press) self.canvas.bind("", self.on_release) self.canvas.bind("<1>", lambda event: self.canvas.focus_set()) self.animate() def on_press(self, event): delta = { "Right": (1,0), "Left": (-1, 0), "Up": (0,-1), "Down": (0,1) } self.direction = delta.get(event.keysym, None) def on_release(self, event): self.direction = None def animate(self): if self.direction is not None: self.canvas.move("ball", *self.direction) self.after(50, self.animate) if __name__ == "__main__": root = tk.Tk() Example(root).pack(fill="both", expand=True) root.mainloop()