我正在寻找一个能执行以下操作的代码片段/示例:
- 显示一条消息,如“按任意键进行配置,或等待X秒后继续” - 等待,例如,5秒后继续执行,或者如果按下了某个键,则进入configure()子程序。
- 显示一条消息,如“按任意键进行配置,或等待X秒后继续” - 等待,例如,5秒后继续执行,或者如果按下了某个键,则进入configure()子程序。
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..."
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..."
Python没有标准方法可以捕获键盘输入,只能通过input()和raw_input()来获取。如果您真的想要这个功能,您可以使用Tkinter或pygame来捕获按键作为“事件”。还有一些特定于平台的解决方案,如pyHook。但是,如果您的程序不绝对需要这个功能,我建议您以其他方式解决问题。
t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()
这是我如何完成它的:
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)
基于https://note.nkmk.me/en/python-while-usage/的想法和其他来源。
如果在5秒内按下CTRL-C,程序将停止,否则将继续运行。
适用于Python 3,不需要任何外部(pip install ...)库。
应该适用于Linux和Windows。
如果您希望程序更频繁地检查用户输入,请在time.sleep()之前注释掉print函数,并将time.sleep(1)更改为time.sleep(0.1)。您可能还会使用顶部的print函数。
import time
def fn_wait_for_user_input(seconds_to_wait,message):
#print('waiting for',seconds_to_wait, 'seconds ...' )
print (message, seconds_to_wait)
start_time = time.time()
try:
while (time.time() - start_time ) < seconds_to_wait:
'''
parenthesis, from inside out:
time.time() which is current time - start time, if it is more than 10 seconds, time's up :)
int ; so we don't count 10 -1,02=8; instead we will count 10-1 = 9, meaning 9 seconds remaining, not 8
seconds to wait - everything else ; so we get reverse count from 10 to 1, not from 1 to 10
'''
print("%d" % ( seconds_to_wait - int( (time.time() - start_time ) ) ) )
time.sleep(1)
print('No keypress detected.')
return 1 #no interrupt after x seconds
except KeyboardInterrupt:
print('Keypress detected - exiting.')
return 0 #interrupted
if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" ) == 1:
print('continuing ....')
else:
print('not continuing.')
print("%d" % ( seconds_to_wait - int( (time.time() - start_time ) ) ), end=' ', flush=True ) #needs flush inside loop...buffered
if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" ) == 1:
#print('continuing ....')
pass
else:
#print('not continuing.')
#exit function
return