2012-08-02 100 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