Usando un buen módulo liviano, podría hacer algo como esto (tomado de su directorio Examples/):
from curtsies import Input
def main():
with Input(keynames='curses') as input_generator:
for e in input_generator:
print(repr(e))
if __name__ == '__main__':
main()
Entonces, presionar las teclas en su teclado le da algo como esto:
'a'
's'
'KEY_F(1)'
'KEY_F(2)'
'KEY_F(3)'
'KEY_F(4)'
'KEY_F(5)'
'KEY_LEFT'
'KEY_DOWN'
'KEY_UP'
'KEY_RIGHT'
'KEY_NPAGE'
'\n'
bpython usa curtsies como una abstracción de bajo nivel de cosas relacionadas con la terminal.
El problema básico de decodificar la entrada es que en diferentes terminales y programas emuladores de terminales como xterm
o gnome-terminals
físicamente las mismas teclas producen diferentes secuencias de códigos de teclas. Es por eso que uno necesita saber qué configuración de terminal se debe usar para decodificar la entrada. Tal módulo ayuda a abstraerse de esos detalles sangrientos.
Este es un ciclo simple que pondrá stdin en modo sin procesar (deshabilitando el almacenamiento en búfer para que no tenga que presionar enter) para obtener caracteres individuales. Deberías hacer algo más inteligente (como un with
declaración para deshabilitarlo) pero entiendes la idea aquí:
import tty
import sys
import termios
orig_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
x = 0
while x != chr(27): # ESC
x=sys.stdin.read(1)[0]
print("You pressed", x)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings)
Creo que tendrías que hacer un bucle para detectar lanzamientos de claves en Python.
ETA alguna explicación más:
En Linux, la entrada a su programa será buffer de línea . Esto significa que el sistema operativo almacenará la entrada en el búfer hasta que tenga una línea completa, por lo que su programa ni siquiera verá nada que el usuario haya escrito hasta que el usuario también presione 'enter'. En otras palabras, si su programa espera que el usuario escriba 'w' y el usuario hace esto, 'w' permanecerá en el búfer del sistema operativo hasta que el usuario presione 'enter'. En este punto, la línea completa se envía a su programa, por lo que obtendrá la cadena "w\n" como entrada del usuario.
Puede deshabilitar esto poniendo el tty en modo sin procesar . Haces esto con la función de Python tty.setcbreak
que hará una llamada al controlador tty en Linux para indicarle que deje de almacenar en búfer. Le pasé el sys.stdin
argumento para decirle para qué flujo quería desactivar el almacenamiento en búfer. Así que después del tty.setcbreak
llamada, el ciclo anterior le dará una salida para cada tecla que presione el usuario.
Sin embargo, una complicación es que una vez que su programa sale, el tty todavía está en modo sin formato. En general, encontrará esto insatisfactorio ya que no obtiene nada de la potencia que ofrecen las configuraciones modernas de terminales (como cuando usa secuencias de control o escape). Por ejemplo, observe que podría tener problemas para salir del programa con ctrl-C
. En consecuencia, debe volver a poner el terminal en modo cocinado una vez que haya terminado de leer los caracteres de entrada. El termios.tcsetattr
call simplemente dice "devolver el terminal a la forma en que lo encontré". Sabe cómo hacer esto llamando primero a termios.tcgetattr
al comienzo del programa que dice "dime todas las configuraciones actuales para el terminal".
Una vez que comprenda todo eso, debería poder encapsular fácilmente la funcionalidad en una función que se adapte a su programa.
stdin
es el flujo que recibe la entrada del usuario. Wikipedia puede brindarle más información sobre transmisiones estándar.