2009-02-22 18 views
7

Tengo que saber qué tecla se pulsa, pero no necesita el código del carácter, quiero saber cuándo alguien presiona la tecla 'A', incluso si la clave obtenida es 'a' o 'A', y así con todas las demás teclas.Cómo obtener los códigos clave en Python

No puedo usar PyGame o cualquier otra biblioteca (incluido Tkinter). Solo la biblioteca estándar de Python. Y esto tiene que hacerse en una terminal, no en una interfaz gráfica.

NO NECESITA EL CÓDIGO DE PERSONAJE. NECESITO SABER EL CÓDIGO CLAVE.

Ex:

ord('a') != ord('A')      # 97 != 65 
someFunction('a') == someFunction('A') # a_code == A_code 
+0

Interfaz gráfica de usuario o terminal? – iny

+0

¿Windows o Linux? Actualice la pregunta, en lugar de agregar otro comentario. –

+0

Actualiza tu pregunta con las marcas "Editar" para mostrar dónde realizaste la pregunta. – myroslav

Respuesta

20

Ver tty módulo estándar. Permite cambiar del modo predeterminado orientado a la línea (cocinado) al modo orientado al carbón (cbreak) con tty.setcbreak(sys.stdin). Lectura single-char de sys.stdin se traducirá en la próxima tecla del teclado prensado (si se genera el código):

import sys 
import tty 
tty.setcbreak(sys.stdin) 
while True: 
    print ord(sys.stdin.read(1)) 

Nota: La solución es Unix (incluyendo Linux) solamente.

Editar: En Windows, pruebe msvcrt.getche()/getwche()./Me tiene donde tratar ...


Edición 2: Utilizar la API de consola Win32 bajo nivel a través de ctypes.windll (ver example at SO) con ReadConsoleInput función. Debe filtrar las pulsaciones de teclas - e.EventType==KEY_EVENT y buscar el valor e.Event.KeyEvent.wVirtualKeyCode. Ejemplo de aplicación (no en Python, solo para tener una idea) se puede encontrar en http://www.benryves.com/tutorials/?t=winconsole&c=4.

+0

repito, no necesito el código de carácter, necesito el código de clave, la presión de la tecla A o MAYÚS + A tiene que ser la misma. El uso de ord() devolverá un valor con A y otro con MAYÚS + A; y con teclas como las flechas no funcionarán –

+0

Creo que la pregunta que hace es de un nivel demasiado bajo. Fue válido en DOS. En la actualidad, el sistema operativo emplea el método de asignación de teclas de las teclas a los símbolos, lo que facilita el cambio de los diseños de teclado (idiomas), por lo que hay pocas posibilidades de obtener pulsaciones de teclas de bajo nivel. solución de pygame eso. – myroslav

+0

bien. Gracias. eso es lo que quiero saber –

9

Dependiendo de lo que está tratando de lograr, tal vez usando una biblioteca como pygame sería hacer lo que quiera. Pygame contiene un manejo de teclas más avanzado que el que normalmente está disponible con las bibliotecas estándar de Python.

+0

gracias, pero no tengo que usar ninguna otra biblioteca aparte de la biblioteca estándar de Python. –

+1

Bien. Dejo esta respuesta aquí (y no la elimino) porque puede ser útil para alguien que viene a hacer una pregunta similar. –

+1

Y a quien desestimó esto: La pregunta original no establecía que pygame no era aceptable. –

3

Probablemente tendrá que usar Tkinter, que es la guía de Python "estándar", y se ha incluido con python durante muchos años.

Una solución de línea de comandos probablemente no esté disponible, debido a la forma en que los datos entran y salen de los procesos de la línea de comandos. Los programas de GUI (de algún tipo u otro) todos reciben la entrada del usuario a través de una secuencia de eventos (posiblemente envuelta por la biblioteca). Cada evento será un registro de los detalles del evento. Para eventos de pulsación de tecla, el registro puede contener cualquier código de clave, campo de bits de tecla modificadora o carácter de texto en alguna codificación. Qué campos y cómo se nombran depende de la biblioteca de eventos a la que está llamando.

Los programas de línea de comandos reciben la entrada del usuario a través de secuencias de caracteres. No hay forma de capturar datos de nivel inferior. Como Myroslav explicó en su publicación, tty's puede estar en modo cocido o crudo, la única diferencia es que en modo cocido el terminal procesará (algunos) caracteres de control para usted, como eliminar e ingresar para que el proceso reciba líneas de entrada, en su lugar de 1 personaje a la vez.

Procesar algo más bajo que eso requiere llamadas al sistema (dependientes del sistema operativo) o abrir dispositivos de caracteres en/dev. La biblioteca estándar de Python no ofrece una función estándar para esto.

0

Si necesita trabajar en Windows solamente, debe intentar msvcrt.

0

La respuesta obvia:

someFunction = string.upper 

ord('a') != ord('A')      # 97 != 65 
someFunction('a') == someFunction('A') # a_code == A_code 

o, en otras palabras (clave):

char_from_user = getch().upper() # read a char converting to uppercase 
if char == 'Q': 
    # quit 
    exit = True # or something 
elif char in ['A', 'K']: 
    do_something() 

etc ...

que aquí hay una implementación de la función getch, que haría trabajo en plataformas Windows y Linux, based on this recipe:

class _Getch(object): 
    """Gets a single character from standard input. 
     Does not echo to the screen.""" 
    def __init__(self): 
     try: 
      self.impl = _GetchWindows() 
     except ImportError: 
      self.impl = _GetchUnix() 

    def __call__(self): 
     return self.impl() 

class _GetchUnix(object): 
    def __init__(self): 
     import tty, sys 

    def __call__(self): 
     import sys, tty, termios 
     fd = sys.stdin.fileno() 
     old_settings = termios.tcgetattr(fd) 
     try: 
      tty.setraw(sys.stdin.fileno()) 
      ch = sys.stdin.read(1) 
     finally: 
      termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 
     return ch 


class _GetchWindows(object): 
    def __init__(self): 
     import msvcrt 

    def __call__(self): 
     import msvcrt 
     return msvcrt.getch() 


getch = _Getch() 
0

esta función devolverá el código del carácter en mayúscula:

def upCcode(ch): 
    if(len(ch) == 1): 
     return ord(ch.upper()) 

y esto es para el código de caracteres en minúsculas:

def lowCcode(ch): 
     if(len(ch) == 1): 
      return ord(ch.lower()) 

esta manera es mucho más fácil, y usted no necesitará importar bibliotecas externas.

Deberá elegir uno de los dos métodos para ser la 'alguna función' que describió en su pregunta. He aquí un ejemplo:

SALIDA:

# when using upCode(): 
>> upCcode('a') 
65 

>> upCcode('A') 
65 

# when using lowCode(): 
>> lowCcode('a') 
97 

>> lowCcode('A') 
97 
Cuestiones relacionadas