键盘输入超时?
Posted
技术标签:
【中文标题】键盘输入超时?【英文标题】:Keyboard input with timeout? 【发布时间】:2010-11-23 01:24:54 【问题描述】:如何提示用户输入一些内容但在 N 秒后超时?
谷歌在http://mail.python.org/pipermail/python-list/2006-January/533215.html 指向一个关于它的邮件线程,但它似乎不起作用。发生超时的语句,不管是sys.input.readline
还是timer.sleep()
,我总是得到:
<type 'exceptions.TypeError'>: [raw_]input expected at most 1 arguments, got 2
except 无法捕捉到。
【问题讨论】:
相关:Python 3 Timed Input Timeout on a Python function call的可能重复 相关:raw_input and timeout /3471461 相关:How to set time limit on input /2933399 独立于平台的 stdlib 解决方案,用于多个输入直到超时:link 【参考方案1】:您可以在 Python >= 3.4 中使用 inputimeout 库。 麻省理工学院许可证。
$ pip install inputimeout
from inputimeout import inputimeout, TimeoutOccurred
try:
something = inputimeout(prompt='>>', timeout=5)
except TimeoutOccurred:
something = 'something'
print(something)
【讨论】:
【参考方案2】:我正在使用外部工具 inputimeout 。源代码可在github 获得。我知道它是一个外部工具,但它很简单而且非常方便。 安装工具后使用此代码:
from inputimeout import inputimeout, TimeoutOccurred
try:
something = inputimeout(prompt='>>', timeout=5)
except TimeoutOccurred:
something = 'No input.'
print(something)
【讨论】:
【参考方案3】:如果您不在乎它是如何工作的,只需 pip install inputimeout
和
from inputimeout import inputimeout, TimeoutOccurred
if __name__ == "__main__":
try:
c = inputimeout(prompt='hello\n', timeout=3)
except TimeoutOccurred:
c = 'timeout'
print(c)
这么简单https://pypi.org/project/inputimeout/
【讨论】:
仅供参考:来自 PyPi 的链接有错字,目前有开放的 PR (#6/#9) 来修复它。源代码在这里:github.com/johejo/inputimeout 在 Windows 上工作!【参考方案4】:这是 linux 上的 python 3.8+ 的另一个,其中包括一个 yes_no 答案,默认返回超时
import signal
def alarm_handler(signum, frame):
raise TimeoutError
def input_with_timeout(prompt, timeout=30):
""" get input with timeout
:param prompt: the prompt to print
:param timeout: timeout in seconds, or None to disable
:returns: the input
:raises: TimeoutError if times out
"""
# set signal handler
if timeout is not None:
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(timeout) # produce SIGALRM in `timeout` seconds
try:
return input(prompt)
except TimeoutError as to:
raise to
finally:
if timeout is not None:
signal.alarm(0) # cancel alarm
def yes_or_no(question, default='y', timeout=None):
""" Get y/n answer with default choice and optional timeout
:param question: prompt
:param default: the default choice, i.e. 'y' or 'n'
:param timeout: the timeout in seconds, default is None
:returns: True or False
"""
if default is not None and (default!='y' and default!='n'):
log.error(f'bad option for default: default')
quit(1)
y='Y' if default=='y' else 'y'
n='N' if default=='n' else 'n'
while "the answer is invalid":
try:
to_str='' if timeout is None else f'(Timeout default in timeouts)'
reply = str(input_with_timeout(f'question to_str (y/n): ',timeout=timeout)).lower().strip()
except TimeoutError:
log.warning(f'timeout expired, returning default=default answer')
reply=''
if len(reply)==0:
return True if default=='y' else False
elif reply[0] == 'y':
return True
if reply[0] == 'n':
return False
代码中的使用示例
if yes_or_no(f'model latest_model_folder exists, start from it?', timeout=TIMEOUT):
log.info(f'initializing model from latest_model_folder')
model = load_model(latest_model_folder)
else:
log.info('creating new empty model')
model = create_model()
【讨论】:
【参考方案5】:有些答案需要在超时发生时按下Enter
键才能继续运行您的代码。其他的似乎很费解,要开机,超时后仍然需要按Enter
键。
我找到了answer in another thread,它工作得很好,但我发现了一个警告。为了便于携带,我决定将我的代码放在class
中。
注意
我不得不使用@987654322@
来注入Enter
按键,因为我的代码中有另一个input()
语句。由于某种原因,除非我按下Enter
键,否则不会出现后续的input()
语句。
import threading
import keyboard # https://github.com/boppreh/keyboard
class Utilities:
# Class variable
response = None
@classmethod
def user_input(cls, timeout):
def question():
cls.response = input("Enter something: ")
t = threading.Thread(target=question)
# Daemon property allows the target function to terminate after timeout
t.daemon = True
t.start()
t.join(timeout)
if cls.response:
# Do something
else:
# Do something else
# Optional. Use if you have other input() statements in your code
keyboard.send("enter")
用法
Utilities.user_input(3)
这是在 Windows 10 上使用 Python 3.8.3 制作的。
【讨论】:
【参考方案6】:这是一个 Python 3.8+(虽然它可以适应 Python 3.6+)跨平台方法,只使用threading
(所以没有multiprocessing
或调用 shell 实用程序)。它旨在从命令行运行脚本,不太适合动态使用。
您可以将内置的input
函数包装如下。在这种情况下,我将内置名称input
重新定义为包装器,因为此实现要求对input
的所有调用都通过此路由。 (免责声明:这就是为什么它可能不是一个好主意,只是为了好玩而已。)
import atexit
import builtins
import queue
import threading
def _make_input_func():
prompt_queue = queue.Queue(maxsize=1)
input_queue = queue.Queue(maxsize=1)
def get_input():
while (prompt := prompt_queue.get()) != GeneratorExit:
inp = builtins.input(prompt)
input_queue.put(inp)
prompt_queue.task_done()
input_thread = threading.Thread(target=get_input, daemon=True)
last_call_timed_out = False
def input_func(prompt=None, timeout=None):
"""Mimics :function:`builtins.input`, with an optional timeout
:param prompt: string to pass to builtins.input
:param timeout: how long to wait for input in seconds; None means indefinitely
:return: the received input if not timed out, otherwise None
"""
nonlocal last_call_timed_out
if not last_call_timed_out:
prompt_queue.put(prompt, block=False)
else:
print(prompt, end='', flush=True)
try:
result = input_queue.get(timeout=timeout)
last_call_timed_out = False
return result
except queue.Empty:
print(flush=True) # optional: end prompt line if no input received
last_call_timed_out = True
return None
input_thread.start()
return input_func
input = _make_input_func()
del _make_input_func
(我在一次性_make_input_func
中定义了设置以在其闭包中隐藏input
的“静态”变量,以避免污染全局命名空间。)
这里的想法是创建一个单独的线程来处理对builtins.input
的所有调用,并使input
包装器管理超时。由于对builtins.input
的调用总是阻塞直到有输入,当超时结束时,特殊线程仍在等待输入,但input
包装器返回(使用None
)。下次调用时,如果上次调用超时,则不需要再次调用builtins.input
(因为输入线程已经在等待输入),只打印提示,然后等待该线程返回一些输入,一如既往。
定义以上内容后,尝试运行以下脚本:
import time
if __name__ == '__main__':
timeout = 2
start_t = time.monotonic()
if (inp := input(f"Enter something (you have timeout seconds): ", timeout)) is not None:
print("Received some input:", repr(inp))
else:
end_t = time.monotonic()
print(f"Timed out after end_t - start_t seconds")
inp = input("Enter something else (I'll wait this time): ")
print("Received some input:", repr(inp))
input(f"Last chance to say something (you have timeout seconds): ", timeout)
【讨论】:
【参考方案7】:已经好几年了,但如果有人碰到这个问题,就像我最近尝试解决这类问题一样,使用func-timeout
包有一种简单快捷的方法来实现这一点。
对于大多数 IDE,它必须在使用前安装;您可以通过pip
安装它。
上面的链接是不言自明的,但我将举例说明我是如何实现它的。
from func_timeout import FunctionTimedOut, func_timeout
try:
ans = func_timeout(5, lambda: int(input('What is the sum of 2 and 3?\n')))
print(ans)
except FunctionTimedOut:
print(5)
func_timeout
在其参数中返回方法的值,在本例中为 question()
函数。它还允许函数所需的其他参数(请参阅文档)。
如果设置的时间过去了(这里是 5 秒),它会引发 TimedOutException
并运行 except
块中的代码。
【讨论】:
这永远不会正常工作:任何对input
的调用都会无限期地阻塞,直到收到一些输入,并且没有办法摆脱。坦率地说,func-timeout
的实现非常糟糕:它试图通过反复“注入”异常来杀死线程,但它甚至不能确保这些异常完成工作(在这种情况下它们不会),它只是等待任意数量并声明线程已成功停止。这意味着stdin
将保持阻塞状态,任何后续的输入调用都将无法正常工作;任何输入都将首先转到 那个 input
调用。
(续) ... 此外,当程序终止时,会发生致命错误,因为 stdin
仍然被守护线程中的 input
调用阻塞:Fatal Python error: could not acquire lock for <_io.BufferedReader name='<stdin>'> at interpreter shutdown, possibly due to daemon threads
。【参考方案8】:
from threading import Thread
import time
def get_input():
while True:
print(input('> '))
t1 = Thread(target=get_input)
t1.setDaemon(True)
t1.start()
time.sleep(3)
print('program exceeds')
只需简单地设置一个新的守护线程,并设置一个睡眠时间,无论你想要什么超时。我认为这很容易赶上XD
【讨论】:
【参考方案9】:受 iperov 的回答启发的解决方案,希望更简洁:
import multiprocessing
import sys
def input_with_timeout(prompt, timeout=None):
"""Requests the user to enter a code at the command line."""
queue = multiprocessing.Queue()
process = multiprocessing.Process(
_input_with_timeout_process, args=(sys.stdin.fileno(), queue, prompt),
)
process.start()
try:
process.join(timeout)
if process.is_alive():
raise ValueError("Timed out waiting for input.")
return queue.get()
finally:
process.terminate()
def _input_with_timeout_process(stdin_file_descriptor, queue, prompt):
sys.stdin = os.fdopen(stdin_file_descriptor)
queue.put(input(prompt))
【讨论】:
【参考方案10】:对于 Linux,我更喜欢 @Pontus 的 select
版本。这里只有一个 python3 函数在 shell 中像 read
一样工作:
import sys, select
def timeout_input(prompt, timeout=3, default=""):
print(prompt, end=': ', flush=True)
inputs, outputs, errors = select.select([sys.stdin], [], [], timeout)
print()
return (0, sys.stdin.readline().strip()) if inputs else (-1, default)
运行
In [29]: timeout_input("Continue? (Y/n)", 3, "y")
Continue? (Y/n):
Out[29]: (-1, 'y')
In [30]: timeout_input("Continue? (Y/n)", 3, "y")
Continue? (Y/n): n
Out[30]: (0, 'n')
还有一个yes_or_no
函数
In [33]: yes_or_no_3 = lambda prompt: 'n' not in timeout_input(prompt + "? (Y/n)", 3, default="y")[1].lower()
In [34]: yes_or_no_3("Continue")
Continue? (Y/n):
Out[34]: True
In [35]: yes_or_no_3("Continue")
Continue? (Y/n): no
Out[35]: False
【讨论】:
对于那些想知道的人 - 这在 Ubuntu 18.04 / 20.04 和 Debian 10 (Buster) 上的 Python 3.7 和 3.8 上完美运行。简短、简单,而且效果很好!【参考方案11】:这就是我处理这个问题的方式。我还没有彻底测试过,我不确定它没有一些重要的问题,但考虑到其他解决方案也远非完美,我决定分享:
import sys
import subprocess
def switch():
if len(sys.argv) == 1:
main()
elif sys.argv[1] == "inp":
print(input(''))
else:
print("Wrong arguments:", sys.argv[1:])
def main():
passw = input_timed('You have 10 seconds to enter password:', timeout=10)
if passw is None:
print("Time's out! You explode!")
elif passw == "PasswordShmashword":
print("H-h-how did you know you h-h-hacker")
else:
print("I spare your life because you at least tried")
def input_timed(*args, timeout, **kwargs):
"""
Print a message and await user input - return None if timedout
:param args: positional arguments passed to print()
:param timeout: number of seconds to wait before returning None
:param kwargs: keyword arguments passed to print()
:return: user input or None if timed out
"""
print(*args, **kwargs)
try:
out: bytes = subprocess.run(["python", sys.argv[0], "inp"], capture_output=True, timeout=timeout).stdout
except subprocess.TimeoutExpired:
return None
return out.decode('utf8').splitlines()[0]
switch()
【讨论】:
你制作了另一个python实例?如果需要一个额外的 python 实例,我不喜欢它。【参考方案12】:修改后的 iperov 答案对我有用 (python3 win10 2019-12-09)
对 iperov 的更改:
将str替换为sstr,因为str是python中的函数
添加导入
添加睡眠以降低 while 循环的 CPU 使用率 (?)
add if name=='main': #windows 上的多处理需要
导入系统、操作系统、多进程、时间
def input_process(stdin_fd, sq, sstr):
sys.stdin = os.fdopen(stdin_fd)
try:
inp = input(sstr)
sq.put(True)
except:
sq.put(False)
def input_in_time(sstr, max_time_sec):
sq = multiprocessing.Queue()
p = multiprocessing.Process(target=input_process, args=( sys.stdin.fileno(), sq, sstr))
p.start()
t = time.time()
inp = False
while True:
if not sq.empty():
inp = sq.get()
break
if time.time() - t > max_time_sec:
break
tleft=int( (t+max_time_sec)-time.time())
if tleft<max_time_sec-1 and tleft>0:
print('\n ...time left '+str(tleft)+'s\ncommand:')
time.sleep(2)
p.terminate()
sys.stdin = os.fdopen( sys.stdin.fileno() )
return inp
if __name__=='__main__':
input_in_time("command:", 17)
【讨论】:
【参考方案13】:我的跨平台解决方案
def input_process(stdin_fd, sq, str):
sys.stdin = os.fdopen(stdin_fd)
try:
inp = input (str)
sq.put (True)
except:
sq.put (False)
def input_in_time (str, max_time_sec):
sq = multiprocessing.Queue()
p = multiprocessing.Process(target=input_process, args=( sys.stdin.fileno(), sq, str))
p.start()
t = time.time()
inp = False
while True:
if not sq.empty():
inp = sq.get()
break
if time.time() - t > max_time_sec:
break
p.terminate()
sys.stdin = os.fdopen( sys.stdin.fileno() )
return inp
【讨论】:
看起来不错,需要试试这个,在while循环中添加sleep不使用太多cpu有意义吗? 尚未测试此解决方案,但我认为不需要睡眠,因为get()
会阻塞直到结果可用。请参阅文档:docs.python.org/3/library/queue.html#queue.Queue.get【参考方案14】:
这是一个使用线程的可移植且简单的 Python 3 解决方案。 这是跨平台时唯一对我有用的。
我试过的其他东西都有问题:
使用 signal.SIGALRM:在 Windows 上不起作用 使用选择调用:不适用于 Windows 使用强制终止进程(而不是线程):标准输入不能用于新进程(标准输入自动关闭) 将标准输入重定向到 StringIO 并直接写入标准输入:如果 input() 已被调用,仍将写入先前的标准输入(请参阅https://***.com/a/15055639/9624704) from threading import Thread
class myClass:
_input = None
def __init__(self):
get_input_thread = Thread(target=self.get_input)
get_input_thread.daemon = True # Otherwise the thread won't be terminated when the main program terminates.
get_input_thread.start()
get_input_thread.join(timeout=20)
if myClass._input is None:
print("No input was given within 20 seconds")
else:
print("Input given was: ".format(myClass._input))
@classmethod
def get_input(cls):
cls._input = input("")
return
【讨论】:
这种方法有效,但线程超时运行。【参考方案15】:以下代码对我有用。
我使用了两个线程,一个用于获取 raw_Input,另一个用于等待特定时间。 如果任何线程退出,则两个线程都将终止并返回。
def _input(msg, q):
ra = raw_input(msg)
if ra:
q.put(ra)
else:
q.put("None")
return
def _slp(tm, q):
time.sleep(tm)
q.put("Timeout")
return
def wait_for_input(msg="Press Enter to continue", time=10):
q = Queue.Queue()
th = threading.Thread(target=_input, args=(msg, q,))
tt = threading.Thread(target=_slp, args=(time, q,))
th.start()
tt.start()
ret = None
while True:
ret = q.get()
if ret:
th._Thread__stop()
tt._Thread__stop()
return ret
return ret
print time.ctime()
t= wait_for_input()
print "\nResponse :",t
print time.ctime()
【讨论】:
【参考方案16】:保罗的回答不太奏效。下面的修改代码对我有用
Windows 7 x64
vanilla CMD shell(例如,not git-bash 或其他非 M$ shell)
-- 没有任何东西 msvcrt
在 git-bash 中出现。
python 3.6
(我正在发布一个新答案,因为直接编辑 Paul 的答案会从 python 2.x-->3.x 更改它,这对于编辑来说似乎太多了(py2 仍在使用中)
import sys, time, msvcrt
def readInput( caption, default, timeout = 5):
start_time = time.time()
sys.stdout.write('%s(%s):'%(caption, default))
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
if ord(byte_arr) == 13: # enter_key
break
elif ord(byte_arr) >= 32: #space_char
input += "".join(map(chr,byte_arr))
if len(input) == 0 and (time.time() - start_time) > timeout:
print("timing out, using default value.")
break
print('') # needed to move to next line
if len(input) > 0:
return input
else:
return default
# and some examples of usage
ans = readInput('Please type a name', 'john')
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 )
print( 'The number is %s' % ans)
【讨论】:
格式化无法正常工作。我很难过,在 Meta 上问过:meta.stackexchange.com/q/290162/208995 当我尝试这个时,我无法输入任何内容(它会等待 5 秒而不让我输入任何内容)。【参考方案17】:类似于 Locane 的 windows:
import subprocess
subprocess.call('timeout /T 30')
【讨论】:
如果重要的话,超时是在 Windows Vista 中或之后引入的。【参考方案18】:不是 Python 解决方案,而是...
我在 CentOS (Linux) 下运行的脚本遇到了这个问题,而对我的情况有用的只是在子进程中运行 Bash“read -t”命令。残酷的令人作呕的黑客,我知道,但我对它的效果感到内疚,所以我想在这里与大家分享。
import subprocess
subprocess.call('read -t 30', shell=True)
我所需要的只是等待 30 秒,除非按下 ENTER 键。这效果很好。
【讨论】:
【参考方案19】:我在这上面花了大约 20 分钟,所以我认为值得一试。不过,它直接建立在 user137673 的答案之上。我发现这样做最有用:
#! /usr/bin/env python
import signal
timeout = None
def main():
inp = stdinWait("You have 5 seconds to type text and press <Enter>... ", "[no text]", 5, "Aw man! You ran out of time!!")
if not timeout:
print "You entered", inp
else:
print "You didn't enter anything because I'm on a tight schedule!"
def stdinWait(text, default, time, timeoutDisplay = None, **kwargs):
signal.signal(signal.SIGALRM, interrupt)
signal.alarm(time) # sets timeout
global timeout
try:
inp = raw_input(text)
signal.alarm(0)
timeout = False
except (KeyboardInterrupt):
printInterrupt = kwargs.get("printInterrupt", True)
if printInterrupt:
print "Keyboard interrupt"
timeout = True # Do this so you don't mistakenly get input when there is none
inp = default
except:
timeout = True
if not timeoutDisplay is None:
print timeoutDisplay
signal.alarm(0)
inp = default
return inp
def interrupt(signum, frame):
raise Exception("")
if __name__ == "__main__":
main()
【讨论】:
很好的解决方案。在 Python3 中工作得很好。投票不够。【参考方案20】:一个迟到的答案:)
我会这样做:
from time import sleep
print('Please provide input in 20 seconds! (Hit Ctrl-C to start)')
try:
for i in range(0,20):
sleep(1) # could use a backward counter to be preeety :)
print('No input is given.')
except KeyboardInterrupt:
raw_input('Input x:')
print('You, you! You know something.')
我知道这不一样,但许多现实生活中的问题都可以通过这种方式解决。 (如果用户暂时不在那里,当我希望某些东西继续运行时,我通常需要用户输入超时。)
希望这至少部分有所帮助。 (如果有人读过它:))
【讨论】:
否,KeyboardInterrupt 异常发生在用户发送中断信号时,通常是在终端上按Ctrl+C。【参考方案21】:这是适用于 Windows 的一个
我无法让这些示例中的任何一个在 Windows 上运行,因此我合并了一些不同的 *** 答案以获得以下结果:
import threading, msvcrt
import sys
def readInput(caption, default, timeout = 5):
class KeyboardThread(threading.Thread):
def run(self):
self.timedout = False
self.input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13:
break
elif ord(chr) >= 32:
self.input += chr
if len(self.input) == 0 and self.timedout:
break
sys.stdout.write('%s(%s):'%(caption, default));
result = default
it = KeyboardThread()
it.start()
it.join(timeout)
it.timedout = True
if len(it.input) > 0:
# wait for rest of input
it.join()
result = it.input
print '' # needed to move to next line
return result
# and some examples of usage
ans = readInput('Please type a name', 'john')
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 )
print 'The number is %s' % ans
【讨论】:
我刚刚意识到我不需要使用线程。在***.com/questions/3471461/raw-input-and-timeout/… 看到相同的代码但没有线程 这似乎不适用于 Windows。除了将 Print 更改为 py3 语法并添加 stdout.flush() 之外,我正在逐字运行您的代码。 Windows7、python3.6 在 Python 3 中,将sys.stdout.write
替换为 print(prompt, end='', flush=True)
以打印提示。【参考方案22】:
使用 select 调用更短,应该更便携
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], [], [], 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
【讨论】:
我刚刚测试过,这不适用于 Windows。 Select 是可用的,但在 Windows 上,select 的输入只能是一个套接字 - sys.stdin 和文件描述符是 unix。下次我一定要先测试。 该死。那么,有什么自尊的程序员使用 Windows 呢? ;) 对于简单的用户输入,我想它可以通过围绕“kbhit”的循环来完成,该循环检测键盘按下,并用“time.sleep”“getch”在超时后中断。但这会很丑。 如果您打算在此调用之后再次从标准输入读取,最好在读取超时的情况下执行termios.tcflush(sys.stdin, termios.TCIFLUSH)
。否则,如果用户输入了字符但没有按 Enter,则终端仿真器可能允许用户按退格键并擦除后续程序输出(最多为用户输入的字符数)。【参考方案23】:
您链接到的示例是错误的,异常实际上是在调用警报处理程序而不是在读取块时发生的。最好试试这个:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
【讨论】:
我今天一直在努力让键盘输入超时。我只是想要一种方法来停止从硬盘驱动器复制图像,这样我只需按一个键就可以停止它,所以我想要一个小的超时(33ms)。我只想指出,您在 *** 上找到的一些解决方案不适用于 IDLE! (我不知道为什么)。您必须在终端上执行它们。而且,我在互联网上找到的最有用的代码是这个:home.wlu.edu/~levys/software/kbhit.py。祝你好运! 我正在尝试这个解决方案,但这在 python3 中不起作用。您必须在中断函数中引发错误才能在定义的输入函数中捕获该异常 - 这将使其在 python3 中工作。 :) 这对我不起作用。它只是在 5 秒后打印"interrupted"
,但实际上并没有停止 input
。它仍然等待 Enter 被按下,甚至在“中断”消息出现后打印我输入的任何文本。使用 Python 2 和 3 在 Linux 上测试。
引用库文档的链接非常有用,以便在它对某人不起作用的情况下进行调试。
您需要为此定义一个处理程序。例如,“def handler(signum, frame): raise IOError”然后是“signal.signal(signal.SIGALRM, handler)”以上是关于键盘输入超时?的主要内容,如果未能解决你的问题,请参考以下文章