我正在尝试制作一个简单的计时器,直到它被键盘输入中断为止。
现在我正在使用CTRL + C来停止计时器,但我想做一些更简单的事情,如点击空格或输入或“任何键”。我听说这可以通过线程模块完成,但经过多次尝试后我显然不知道我在做什么。
这是我目前的代码:
def countup():
try:
a=0
for i in range(1000000) :
print i,'\r',
time.sleep(1)
except KeyboardInterrupt:
Z = raw_input("restart timer?" )
if Z == "Y" or Z == "y" :
countup()
答案 0 :(得分:4)
使用thread和terminal capabilities可以写(按任意键停止):
import thread
import time
def read_key():
import termios
import sys
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
new = termios.tcgetattr(fd)
new[3] &= ~(termios.ICANON | termios.ECHO) # c_lflags
c = None
try:
termios.tcsetattr(fd, termios.TCSANOW, new)
c = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSANOW, old)
return c
def input_thread():
read_key()
thread.interrupt_main()
def countup():
try:
thread.start_new_thread(input_thread, ())
for i in range(1000000):
print i
time.sleep(1)
except KeyboardInterrupt:
Z = raw_input("restart timer? ")
if Z == 'y' or Z == 'Y':
countup()
让我们澄清一下:
thread.start_new_thread()
使用input_thread()
作为启动函数创建一个新线程。虽然thread.interrupt_main()
在主线程中提升KeyboardInterrupt
。
termios.tcgetattr()
返回当前终端属性。 ~termios.ICANON
取消设置canonical模式,~termios.ECHO
阻止输入打印,然后termios.tsetattr()
执行更改。
或者,在Windows上,可以使用msvcrt中的getch()
代替read_key()
def input_thread():
msvcrt.getch()
thread.interrupt_main()
答案 1 :(得分:0)
您的代码有两个问题:
问题是您需要尝试从stdin读取,但不要等到输入出现在那里,如果没有任何开头。 This page提供了如何执行此操作的详细说明。
根据上面的链接,如果你点击输入,这段代码应该可以使计数停止:
import sys
import select
import time
def countup():
i = 0
while True:
print i
i += 1
time.sleep(1)
while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
line = sys.stdin.readline()
if line:
r = raw_input("Restart?")
if r.lower() == "y":
countdown()
else:
break
countup()