2012-08-29 17 views
33

Sono nuovo di Python e ho appena creato un gioco e un menu in Python. La domanda è, che usando (raw_) input() mi imponga di premere Invio dopo ogni pressione di un tasto, mi piacerebbe farlo in modo che premendo la freccia verso il basso si selezioni istantaneamente la voce successiva del menu, o si scorra nel gioco. Al momento, mi richiede di digitare "down" e poi premere invio. Ho anche fatto un sacco di ricerche, ma preferirei non scaricare enormi moduli (ad es. Pygame) solo per ottenere un singolo metodo keyDown(). Quindi ci sono modi più semplici, che non riuscivo a trovare?Metodo Python per la lettura della pressione di un tasto?

Modifica: Ho appena scoperto che lo msvcrt.getch() avrebbe fatto il trucco. Non è keyDown(), ma funziona. Tuttavia, non sono sicuro di come usarlo, sembra abbastanza strano, qualche aiuto qui? Questo è quello che ho ottenuto in questo momento:

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

Tuttavia, continua a darmi tutti questi byte senza senso, per esempio, freccia giù è questo:

b'\xe0' 
b'P' 

e non ho idea di come li uso, ho provato a confrontarmi con chr() e anche ad usare ord() ma non posso davvero fare confronti. Quello che sto cercando di fare è fondamentalmente questo:

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

E così via ... Qualsiasi aiuto?

+0

Non un duplicato di quello. Si tratta di eventi di keydown, non di input di singoli caratteri. – Deestan

+7

Posso avere una soluzione multipiattaforma ?? 'msvcrt' non è disponibile sulle distribuzioni mac/linux di Python – cat

risposta

47

Capito da tutte le prove da solo. Non ho trovato nessun argomento a riguardo, quindi lascerò qui la soluzione. Questa potrebbe non essere l'unica o anche la soluzione migliore, ma funziona per i miei scopi (entro i limiti di getch) ed è meglio di niente.

Nota: corretto keyDown() che riconoscerebbe tutte le chiavi e le pressioni effettive dei tasti, è ancora valutato.

Soluzione: usando ord() -funzione per accendere prima il getch() in un numero intero (immagino che siano codici chiave virtuali, ma non troppo sicuro) funziona bene, e poi confrontando il risultato per il numero effettivo che rappresenta la voleva chiave. Inoltre, se necessario, potrei aggiungere un ulteriore chr() attorno al numero restituito in modo che possa convertirlo in un personaggio. Comunque, sto usando principalmente down arrow, esc, ecc. Quindi convertirli in un personaggio sarebbe stupido.Ecco il codice finale:

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

anche se qualcun altro ha bisogno di, si può facilmente scoprire i keycodes da Google, oppure utilizzando Python e semplicemente premendo il tasto:

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

Grazie, questa è stata la prima risposta che ha funzionato per me. +1 –

+1

Sto usando il codice sopra, ma il mio codice semplicemente blocca su getch(), e poi non succede nulla. qualsiasi aiuto ? –

+1

@AnumSheraz Il metodo precedente funziona solo quando si esegue il codice dal prompt dei comandi. – Moondra

8

Vedere i documenti MSDN getch. In particolare:

Le funzioni _getch e_getwch leggono un singolo carattere dalla console senza riecheggiare il carattere. Nessuna di queste funzioni può essere utilizzata per leggere CTRL + C. Quando si legge un tasto funzione o un tasto freccia, ciascuna funzione deve essere chiamata due volte; la prima chiamata restituisce 0 o 0xE0 e la seconda chiamata restituisce il codice effettivo della chiave.

La funzione Python restituisce un carattere. è possibile utilizzare ord() per ottenere un valore intero che è possibile testare, ad esempio keycode = ord(msvcrt.getch()).

Quindi, se si legge un 0x00 o 0xE0, leggerlo una seconda volta per ottenere il codice chiave per una freccia o un tasto funzione. Dalla sperimentazione, 0x00 precede F1-F10 (0x3B-0x44) e 0xE0 precede i tasti freccia e Ins/Canc/Home/Fine/PageUp/PageDown.

+0

Beh, l'ho capito, ma non posso pubblicare la soluzione finale. Ma questo + 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

Aggiungi alcune spiegazioni alla tua risposta per spiegare il tuo codice. – AJ123