2012-08-29 30 views
33

Soy nuevo en Python, y acabo de hacer un juego y un menú en Python. La pregunta es, que el uso de (raw_) input() requiere que presione enter luego de cada pulsación de tecla, me gustaría hacerlo de modo que al presionar la flecha hacia abajo se seleccione al instante el siguiente elemento del menú, o mueva hacia abajo en el juego. Por el momento, requiere que me guste escribir "abajo" y luego presionar enter. También investigué bastante, pero preferiría no descargar módulos grandes (por ejemplo, pygame) solo para lograr un único método keyDown(). Entonces, ¿hay alguna manera más fácil, que simplemente no pude encontrar?Método de Python para leer la pulsación de tecla?

Editar: Acaba de descubrir que msvcrt.getch() haría el truco. No es KeyDown(), pero funciona. Sin embargo, no estoy seguro de cómo usarlo, parece bastante extraño, ¿alguna ayuda aquí? Esto es lo que tengo en este momento:

from msvcrt import getch 
while True: 
    key = getch() 
    print(key) 

Sin embargo, me mantiene dando todos estos bytes sin sentido, por ejemplo, la flecha hacia abajo es la siguiente:

b'\xe0' 
b'P' 

y no tengo ni idea de cómo úsalos, he intentado comparar con chr() e incluso usar ord() pero realmente no puedo hacer ninguna comparación. Lo que estoy tratando de hacer es básicamente esto:

from msvcrt import getch 
while True: 
    key = getch() 
    if key == escape: 
     break 
    elif key == downarrow: 
     movedown() 
    elif key == 'a': 
     ... 

Y así sucesivamente ... ¿Alguna ayuda?

+0

No es una duplicado de eso. Se trata de eventos de pulsación, no de entrada de un solo carácter. – Deestan

+7

¿Puedo hacer una solución multiplataforma? 'msvcrt' no está disponible en las distribuciones mac/linux de Python – cat

Respuesta

47

Lo averigué probando todo el contenido yo solo. No pude encontrar ningún tema al respecto, así que simplemente dejaré la solución aquí. Puede que esta no sea la única ni la mejor solución, pero funciona para mis propósitos (dentro de los límites de getch) y es mejor que nada.

Nota: keyDown() adecuado que reconocería todas las teclas y las pulsaciones de teclas reales, todavía se valora.

Solución: usando ord() -función para activar la primera getch() en un entero (supongo que son los códigos de teclas virtuales, pero no demasiado seguro) funciona bien, y luego comparando el resultado con el número real que representa el querido llave. Además, si lo necesitaba, podría agregar un chr() extra alrededor del número devuelto para que se convierta en un personaje. Sin embargo, estoy usando principalmente flecha hacia abajo, esc, etc. por lo que convertirlos en un personaje sería estúpido.Aquí está el código final:

from msvcrt import getch 
while True: 
    key = ord(getch()) 
    if key == 27: #ESC 
     break 
    elif key == 13: #Enter 
     select() 
    elif key == 224: #Special keys (arrows, f keys, ins, del, etc.) 
     key = ord(getch()) 
     if key == 80: #Down arrow 
      moveDown() 
     elif key == 72: #Up arrow 
      moveUp() 

Además, si alguien necesita, se puede encontrar fácilmente los códigos de teclas de Google, o mediante el uso de Python y simplemente pulsando la tecla:

from msvcrt import getch 
while True: 
    print(ord(getch())) 
+2

Gracias, esta fue la primera respuesta que funcionó para mí. +1 –

+1

Estoy usando el código anterior, pero mi código simplemente bloquea en getch(), y no pasa nada entonces. alguna ayuda ? –

+1

@AnumSheraz El método anterior solo funciona cuando ejecuta el código desde el símbolo del sistema. – Moondra

8

Consulte los documentos de MSDN getch. Específicamente:

Las funciones _getch y_getwch leen un único carácter de la consola sin hacer eco del carácter. Ninguna de estas funciones se puede usar para leer CTRL + C. Al leer una tecla de función o una tecla de flecha, cada función debe ser llamada dos veces; la primera llamada devuelve 0 o 0xE0, y la segunda llamada devuelve el código de tecla real.

La función Python devuelve un carácter. puede usar ord() para obtener un valor entero que puede probar, por ejemplo keycode = ord(msvcrt.getch()).

Si lee 0x00 o 0xE0, léelo una segunda vez para obtener el código de tecla de una flecha o tecla de función. A partir de la experimentación, 0x00 precede a F1-F10 (0x3B-0x44) y 0xE0 precede a las teclas de flecha y Ins/Supr/Inicio/Fin/RePág/Descendida.

+0

Bueno, ya lo imaginé, pero no puedo publicar la solución final. Pero esto + ord() + char() –

0
from msvcrt import getch 

pos = [0, 0] 

def fright(): 
    global pos 
    pos[0] += 1 

def fleft(): 
    global pos 
    pos[0] -= 1 

def fup(): 
    global pos 
    pos[1] += 1 

def fdown(): 
    global pos 
    pos[1] -= 1 

while True: 
    print'Distance from zero: ', pos 
    key = ord(getch()) 
    if key == 27: #ESC 
     break 
    elif key == 13: #Enter 
     print('selected') 
    elif key == 32: #Space 
     print('jump') 
    elif key == 224: #Special keys (arrows, f keys, ins, del, etc.) 
     key = ord(getch()) 
     if key == 80: #Down arrow 
      print('down') 
      fdown 
     elif key == 72: #Up arrow 
      print('up') 
      fup() 
     elif key == 75: #Left arrow 
      print('left') 
      fleft() 
     elif key == 77: #Right arrow 
      print('right') 
      fright() 
+2

Agregue algunas explicaciones a su respuesta para explicar su código. – AJ123

Cuestiones relacionadas