Python等待x秒获取密钥,如果未按下则继续执行

时间:2011-05-30 18:20:26

标签: python wait

我是python的n00b,我正在寻找执行以下操作的代码段/示例:

  • 显示“按任意键配置或等待X秒继续”等消息
  • 等待,例如,5秒钟继续执行,或者如果按下某个键,则输入configure()子程序。

感谢您的帮助!

Yvan Janssens

4 个答案:

答案 0 :(得分:18)

如果您使用的是Unix / Linux,那么select模块将为您提供帮助。

import sys
from select import select

print "Press any key to configure or wait 5 seconds..."
timeout = 5
rlist, wlist, xlist = select([sys.stdin], [], [], timeout)

if rlist:
    print "Config selected..."
else:
    print "Timed out..."

如果您使用的是Windows,请查看msvcrt模块。 (注意这在IDLE中不起作用,但在cmd提示符下也是如此)

import sys, time, msvcrt

timeout = 5
startTime = time.time()
inp = None

print "Press any key to configure or wait 5 seconds... "
while True:
    if msvcrt.kbhit():
        inp = msvcrt.getch()
        break
    elif time.time() - startTime > timeout:
        break

if inp:
    print "Config selected..."
else:
    print "Timed out..."

修改更改了代码示例,以便判断是否存在超时或按键...

答案 1 :(得分:1)

Python没有任何标准方法来捕获它,它只通过input()和raw_input()获取键盘输入。

如果你真的想要这个,你可以使用Tkinter或pygame将键击捕获为“事件”。还有一些特定于平台的解决方案,如pyHook。但如果它对你的程序不是绝对重要的,我建议你让它以另一种方式工作。

答案 2 :(得分:1)

If you combine time.sleep, threading.Thread, and sys.stdin.read you can easily wait for a specified amount of time for input and then continue.

t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()

答案 3 :(得分:1)

这是我的做法:

import threading
import time
import sys


class MyThread(threading.Thread):
    def __init__(self, threadID, name, counter, f):
        super().__init__()
        self.threadID = threadID
        self.name = name
        self.counter = counter
        self.func = f

    def run(self):
        self.func()

class KeyboardMonitor:
    def __init__(self):
        # Setting a boolean flag is atomic in Python.
        # It's hard to imagine a boolean being 
        # anything else, with or without the GIL.
        # If inter-thread communication is anything more complicated than
        # a couple of flags, you should replace low level variables with 
        # a thread safe buffer.
        self.keepGoing = True

    def wait4KeyEntry(self):
        while self.keepGoing:
            s = input("Type q to quit: ")
            if s == "q":
                self.keepGoing = False

    def mainThread(self, f, *args, **kwargs):
        """Pass in some main function you want to run, and this will run it
        until keepGoing = False. The first argument of function f must be 
        this class, so that that function can check the keepGoing flag and 
        quit when keepGoing is false."""
        keyboardThread = MyThread(1, "keyboard_thread", 0, self.wait4KeyEntry)
        keyboardThread.start()
        while self.keepGoing:
            f(self, *args, **kwargs)

def main(keyMonitorInst, *args, **kwargs):
    while keyMonitorInst.keepGoing:
        print("Running again...")
        time.sleep(1)

if __name__ == "__main__":
    uut = KeyboardMonitor()
    uut.mainThread(main)

我的方法不是启动阻塞超时,而是启动一个线程,等待用户输入输入,而另一个线程执行其他操作。这两个进程通过少量的原子操作进行通信:在这种情况下,设置一个布尔标志。对于比原子操作更复杂的事情,显然您应该用某种线程安全缓冲区替换原子变量。