2009-02-22 9 views
7

Devo sapere quale tasto viene premuto, ma non è necessario il codice del Carattere, voglio sapere quando qualcuno preme il tasto 'A' anche se la chiave ottenuta è 'a' o 'A', e così con tutte le altre chiavi.Come ottenere i keycode in Python

Non riesco a utilizzare PyGame o qualsiasi altra libreria (incluso Tkinter). Solo la libreria standard Python. E questo deve essere fatto in un terminale, non in un'interfaccia grafica.

NON NECESSARIO IL CODICE DI CARATTERE. HO BISOGNO DI CONOSCERE IL CODICE CHIAVE.

Es:

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

Interfaccia utente grafica o terminale? – iny

+0

Windows o Linux? Si prega di aggiornare la domanda, piuttosto che aggiungere ancora un altro commento. –

+0

Si prega di aggiornare la domanda con i segni "Modifica" per mostrare dove hai avanzato la domanda. – myroslav

risposta

20

Vedere modulo standard tty. Permette di passare dalla modalità predefinita orientata alla linea (cotto) in modalità char-oriented (cbreak) con tty.setcbreak(sys.stdin). Leggendo singolo carattere da sys.stdin si tradurrà in prossimo tasto della tastiera premuto (se genera il codice):

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

Nota: la soluzione è Unix (compreso Linux) solo.

Modifica: su Windows provare msvcrt.getche()/getwche()./Me ha un posto dove provare ...


Edit 2: Utilizzare win32 basso livello console API tramite ctypes.windll (vedi example at SO) con ReadConsoleInput la funzione. È necessario filtrare i tasti - e.EventType==KEY_EVENT e cercare il valore e.Event.KeyEvent.wVirtualKeyCode. Esempio di applicazione (non in Python, solo per avere un'idea) può essere trovato a http://www.benryves.com/tutorials/?t=winconsole&c=4.

+0

ripeti, non ho bisogno del codice carattere, ho bisogno del KeyCode, la pressione del tasto A o MAIUSC + A deve essere la stessa. L'uso di ord() restituirà un valore con A e un altro con SHIFT + A; e le chiavi come le frecce non funzioneranno –

+0

Penso che la domanda che stai facendo sia troppo bassa. Era valido in DOS. Al giorno d'oggi il sistema operativo impiega l'approccio di keymapping dalle chiavi ai simboli, facilitando il cambio di layout di tastiera (lingue), quindi ci sono poche possibilità di accedere a pressioni di tasto di basso livello. Pygame soluzione. – myroslav

+0

ok. Grazie. questo è quello che voglio sapere –

9

seconda di cosa si sta cercando di realizzare, magari utilizzando una libreria come pygame sarebbe fare quello che vuoi. Pygame contiene una gestione più avanzata dei tasti rispetto a quella normalmente disponibile con le librerie standard di Python.

+0

grazie, ma non ho bisogno di usare qualsiasi altra libreria rispetto alla libreria python standard. –

+1

Ok. Lascio questa risposta qui (e non la cancellerò) perché potrebbe essere utile a qualcun altro che viene qui a fare una domanda simile. –

+1

E a chi ha downvoted questo: la domanda originale non affermava che pygame non era accettabile. –

3

Probabilmente sarà necessario utilizzare Tkinter, che è il gui Python "standard" ed è stato incluso in Python per molti anni.

Una soluzione da riga di comando non è probabilmente disponibile, a causa del modo in cui i dati passano da e verso i processi della riga di comando. I programmi GUI (di qualche tipo o altro) ricevono tutti gli input dell'utente attraverso un flusso di eventi (eventualmente con una libreria avvolta). Ogni evento sarà una registrazione dei dettagli dell'evento. Per gli eventi di battitura, il record può contenere qualsiasi codice di accesso, tasto di modifica bitfield o carattere di testo in alcune codifiche. Quali campi e come vengono denominati dipendono dalla libreria di eventi che si sta chiamando.

I programmi della riga di comando ricevono l'input dell'utente tramite i flussi di caratteri. Non c'è modo di rilevare i dati di livello inferiore. Come spiegato dal myroslav nel suo post, le tty possono essere in modalità cotte o non cotte, l'unica differenza è che in modalità cotta il terminale elabora (alcuni) i caratteri di controllo per te, come cancella ed entra in modo che il processo riceva linee di input, invece di 1 carattere alla volta.

L'elaborazione di qualsiasi numero inferiore a quello richiede chiamate di sistema (dipendenti dall'OS) o dispositivi di carattere di apertura in/dev. La libreria standard di Python non fornisce funzionalità standard per questo.

0

Se è necessario lavorare in Windows, è necessario provare msvcrt.

0

La risposta ovvia:

someFunction = string.upper 

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

o, in altre (chiave) parole:

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() 

ecc ...

Ecco un'implementazione della funzione getch, che avrebbe lavoro su entrambe le piattaforme Windows e 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

questa funzione restituisce il codice per il carattere maiuscolo:

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

e questo è per il codice di carattere minuscolo:

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

questo modo è molto più facile, e non sarà necessario importare librerie esterne.

Sarà necessario scegliere uno dei due metodi per essere il 'qualcheFunzione' che hai descritto nella domanda. Ecco un esempio:

USCITA:

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

>> upCcode('A') 
65 

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

>> lowCcode('A') 
97