我正在用Python编写一个程序来运行我的Raspberry Pi。正如许多人所知,Raspberry可以获得许多输入方式。我正在使用键盘和另一个外部输入源。这只是用于语境化,对于问题本身并不重要。
在我的程序中,我等待键盘输入,如果在短时间内没有,我跳过并查找来自其他来源的输入。为此,我使用以下代码:
import sys
import time
from select import select
timeout = 4
prompt = "Type any number from 0 up to 9"
default = 99
def input_with(prompt, timeout, default):
"""Read an input from the user or timeout"""
print prompt,
sys.stdout.flush()
rlist, _, _ = select([sys.stdin], [], [], timeout)
if rlist:
s = int(sys.stdin.read().replace('\n',''))
else:
s = default
print s
return s
我打算在没有全键盘的情况下运行Raspberry Pi,这意味着我没有返回键。以这种方式验证键盘输入是不可能的。
我怀疑的是,是否可以在不按Enter键的情况下获取用户输入并保持输入超时。
我已经看到很多话题都在谈论这两个问题(超时和输入而没有按回复)但两者都没有。
提前感谢您的帮助!
答案 0 :(得分:0)
我不认为以你想要的方式做到这一点是直截了当的,即读取线上的等待内容,即使没有按下输入(这是对的?)。
我能提供的最佳建议是在按下每个角色时捕捉它们,并在时间过去后调用。您可以通过设置 cbreak 模式来捕获每个字符的输入:tty.setcbreak()
import sys
from select import select
import tty
import termios
try:
# more correct to use monotonic time where available ...
from time33 import clock_gettime
def time(): return clock_gettime(0)
except ImportError:
# ... but plain old 'time' may be good enough if not.
from time import time
timeout = 4
prompt = "Type any number from 0 up to 9"
default = 99
def input_with(prompt, timeout, default):
"""Read an input from the user or timeout"""
print prompt,
sys.stdout.flush()
# store terminal settings
old_settings = termios.tcgetattr(sys.stdin)
buff = ''
try:
tty.setcbreak(sys.stdin) # flush per-character
break_time = time() + timeout
while True:
rlist, _, _ = select([sys.stdin], [], [], break_time - time())
if rlist:
c = sys.stdin.read(1)
# swallow CR (in case running on Windows)
if c == '\r':
continue
# newline EOL or EOF are also end of input
if c in ('\n', None, '\x04'):
break # newline is also end of input
buff += c
sys.stdout.write(c) # echo back
sys.stdout.flush()
else: # must have timed out
break
finally:
# put terminal back the way it was
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
if buff:
return int(buff.replace('\n','').strip())
else:
sys.stdout.write('%d' % default)
return default