2012-08-02 13 views
5

Come posso aspettare che l'utente preme un tasto per 20 secondi? Cioè Io mostro il messaggio e conta 20 secondi, il codice continua l'esecuzione se vengono passati 20 secondi OPPURE se l'utente ha premuto un tasto qualsiasi. Come posso farlo con Python?Come aspettare 20 secondi per l'utente per premere un tasto?

+2

Consulti non bloccante ingresso, poi attuare tale in un ciclo while che controlla l'ora corrente rispetto all'orario di partenza. – Lanaru

+1

@Lanaru: perché un ciclo? Sembra un brutto caso di busy-waiting. Qualcosa come 'select()' con un timeout potrebbe fare la stessa cosa. – gsk

+0

_press qualsiasi chiave_ non è uguale _input any string_ – moooeeeep

risposta

7

Se siete su Windows:

def wait_for_user(secs): 
    import msvcrt 
    import time 
    start = time.time() 
    while True: 
     if msvcrt.kbhit(): 
      msvcrt.getch() 
      break 
     if time.time() - start > secs: 
      break 
+0

È un po 'meschino, ma se qualcuno colpisce un personaggio durante il sonno, stai aspettando senza motivo. Meglio confrontare il tempo piuttosto che dormire. – Logan

+0

Hai ragione. Aggiornato per confrontare il tempo. –

0

(Attenzione: codice non testato)

Qualcosa di simile:

import sys 
import select 

rlist, _, _ = select.select([sys.stdin], [], [], timeout=20) 
if len(rlist) == 0: 
    print "user didnt input anything within 20 secs" 
else: 
    print "user input something within 20 secs. Now you just have to read it" 

modificare vedi: http://docs.python.org/library/select.html

+1

Non sapevo del modulo di selezione, è bello sapere. L'ho appena testato su Windows e non ha funzionato. Da documenti: Nota: gli oggetti file su Windows non sono accettabili, ma i socket sono. Su Windows, la funzione select() sottostante è fornita dalla libreria WinSock e non gestisce i descrittori di file che non provengono da WinSock. –

+0

@BrendenBrown: Wow, non ne avevo idea. Grazie per l'aggiornamento (questo promuove la mia confusione allo sviluppo di Windows ...) – gsk

2

Una possibile la soluzione è usare select per verificare i valori, ma non mi piace, mi sento come se stessi perdendo il mio tempo.
D'altra parte è possibile utilizzare la segnalazione su sistemi Linux per gestire il problema. dopo un certo periodo di tempo, un'eccezione viene sollevata, try fallisce e codice continua in except:

import signal 

class AlarmException(Exception): 
    pass 

def alarmHandler(signum, frame): 
    raise AlarmException 

def nonBlockingRawInput(prompt='', timeout=20): 
    signal.signal(signal.SIGALRM, alarmHandler) 
    signal.alarm(timeout) 
    try: 
     text = raw_input(prompt) 
     signal.alarm(0) 
     return text 
    except AlarmException: 
     print '\nPrompt timeout. Continuing...' 
    signal.signal(signal.SIGALRM, signal.SIG_IGN) 
    return '' 

Il codice è stato preso da here

+0

Mi piace questo, ma non funziona anche su Windows. – mgilson

+0

Anche nel tuo caso speciale ha un'altra trappola che è 'raw_input' aspetta che entri' \ n' alla fine, perché Python è in modalità bufferizzata di linea per impostazione predefinita. – Rsh

Problemi correlati