tutorial tamaño how gui example entry python user-interface keyboard user-input interactive

python - tamaño - Manejo efectivo de entradas de teclado



tkinter python 3 (3)

¿Cuál es una buena manera de implementar el manejo del teclado? En cualquier idioma, donde escribo un programa de teclado interactivo (como un juego de tetris), termino teniendo un código que se ve así:

for event in pygame.event.get(): if event.type == KEYDOWN: if False: pass #make everything an elif elif rotating: pass elif event.key == K_q: elif event.key == K_e: elif event.key == K_LEFT: curpiece.shift(-1, 0) shadowpiece = curpiece.clone(); setupshadow(shadowpiece) elif event.key == K_RIGHT: curpiece.shift(1, 0) shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

(acortado). No me gusta esto, ya que esto tiene que ir en mi ciclo principal, y se mete con todas las partes del programa. Esto también hace que sea imposible tener una pantalla de configuración de usuario donde puedan cambiar qué mapas de teclas y qué acción. ¿Hay un buen patrón para hacer esto usando alguna forma de devoluciones de función?


Lo que hago hoy en día es tener algún tipo de clase / función / hilo de recopilación de datos de entrada que verifique una lista de enlaces predefinidos de tecla-> evento.

Algo como esto:

class InputHandler: def __init__ (self, eventDispatcher): self.keys = {} self.eventDispatcher = eventDispatcher def add_key_binding (self, key, event): self.keys.update((key, event,)) def gather_input (self): for event in pygame.event.get(): if event.type == KEYDOWN: event = self.keys.get(event.key, None) if not event is None: self.eventDispatcher.dispatch(event) .... inputHandler = InputHandler(EventDispatcher) inputHandler.add_key_binding(K_q, "quit_event") ... inputHandler.gather_input() ....

Básicamente es lo que superjoe30 está haciendo, excepto que en lugar de llamar devoluciones de llamada directamente, agrego otro nivel de separación mediante el uso de un sistema de envío de eventos, de modo que cualquier código que se preocupe por las teclas presionadas simplemente escuche ese evento.

Además, las claves se pueden vincular fácilmente a diferentes eventos, que se pueden leer desde un archivo de configuración o algo así y cualquier clave que no esté vinculada a un evento simplemente se ignora.


Puede crear un diccionario donde las claves sean la entrada y el valor sea una función que maneje la pulsación de tecla:

def handle_quit(): quit() def handle_left(): curpiece.shift(-1, 0) shadowpiece = curpiece.clone(); setupshadow(shadowpiece) def handle_right(): curpiece.shift(1, 0) shadowpiece = curpiece.clone(); setupshadow(shadowpiece) def handle_pause(): if not paused: paused = True branch = { K_q: handle_quit K_e: handle_pause K_LEFT: handle_left K_RIGHT: handle_right } for event in pygame.event.get(): if event.type == KEYDOWN: branch[event.key]()

Entonces, cambiar las claves es una cuestión de modificar las claves del diccionario.


Además de la respuesta de Superjoe30 , puedes usar dos niveles de mapeo (dos diccionarios)

  • clave => cadena de comando
  • cadena de comando => función

Creo que esto haría que sea más fácil permitir asignaciones definidas por el usuario. es decir, los usuarios pueden asignar sus claves a "comandos" en lugar de "el nombre de una función"