2012-08-02 101 views
5

如何等待用戶按任意鍵20秒?即我顯示消息並計數20秒,如果通過20秒或者如果用戶按下任何鍵,則代碼繼續執行。我如何用python來做到這一點?如何等待20秒讓用戶按任意鍵?

+2

採取查找非阻塞輸入,然後實現在while循環中檢查當前時間與開始時間的比較。 – Lanaru 2012-08-02 19:10:45

+1

@Lanaru:爲什麼一段時間循環?聽起來像是忙碌等待的糟糕情況。類似'select()'的超時可以做同樣的事情。 – gsk 2012-08-02 19:14:20

+0

_press任何key_不等於_input任何string_ – moooeeeep 2012-08-02 19:22:35

回答

7

如果您使用的是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

這是一個小瑣事,但如果有人在過程中擊中一個字符睡眠,你無緣無故等待。最好比較時間而不是睡眠。 – Logan 2012-08-02 19:29:44

+0

你說得對。更新以比較時間。 – 2012-08-02 20:33:47

0

(警告:未經測試的代碼)

喜歡的東西:

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" 

編輯見:http://docs.python.org/library/select.html

+1

我不知道選擇模塊,這是很好的瞭解。我只是在Windows上測試它,並沒有奏效。從文檔: 注意:Windows上的文件對象不可接受,但套接字是。在Windows上,底層的select()函數由WinSock庫提供,並且不處理源自WinSock的文件描述符。 – 2012-08-02 19:21:08

+0

@BrendenBrown:哇,我不知道。感謝您的更新(這進一步加劇了我在Windows開發中的困惑......) – gsk 2012-08-02 19:22:23

2

一種可能解決方案是使用select檢查值,但我不喜歡它,我覺得我浪費我的時間。
另一方面,您可以在Linux系統上使用信號處理該問題。一定的時間後,將引發異常,try失敗,代碼繼續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 '' 

的代碼已經從here

+0

我喜歡這個,但它在Windows上也不起作用。 – mgilson 2012-08-02 19:36:00

+0

在你的特殊情況下,它還有另一個缺陷,就是'raw_input'等待你在最後輸入'\ n',因爲默認情況下Python處於行緩衝模式。 – Rsh 2012-08-02 19:40:40