Python中使用sleep()时如何停止读取stdin输入?
解决Unix命令行动画播放时的输入干扰问题
针对你在命令行游戏中播放动画时,用户输入会在动画结束后被批量处理的问题,提供两种可行方案:
方案一:播放动画时禁用终端输入
在动画开始前,先保存终端的原始属性,切换到终端默认模式(禁用即时输入),动画结束后再恢复回原始模式(支持按键即时读取)。这种方式能彻底阻止动画期间的输入被缓冲。
示例代码:
import sys import tty import termios import time # 提前保存终端原始配置 old_term_settings = termios.tcgetattr(sys.stdin) running = True spacebar_key = ord(' ') frames = ["[=====]", "[======]", "[=======]", "[========]"] try: # 设置终端为原始模式,支持即时读取按键 tty.setraw(sys.stdin) while running: pressed_key = ord(sys.stdin.read(1)) if pressed_key == spacebar_key: # 切换回终端默认模式,暂时禁用即时输入 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_term_settings) # 播放动画帧 for frame in frames: # 用ANSI转义码清屏并定位光标到左上角 print("\033[H\033[J", end="") print(f"加载中: {frame}") time.sleep(0.2) # 动画结束后,重新恢复原始模式 tty.setraw(sys.stdin) # 按q键退出程序 elif pressed_key == ord('q'): running = False finally: # 程序退出前,强制恢复终端原始配置,避免终端异常 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_term_settings)
方案二:动画结束后清空输入缓冲区
如果不想完全禁用动画期间的输入,可以在动画结束后,检查并清空stdin的缓冲输入,丢弃用户在动画期间按下的所有按键。
示例代码:
import sys import tty import time import select running = True spacebar_key = ord(' ') frames = ["[=====]", "[======]", "[=======]", "[========]"] try: tty.setraw(sys.stdin) while running: # 使用select检查是否有可读的输入,避免阻塞游戏循环 if select.select([sys.stdin], [], [], 0.01)[0]: pressed_key = ord(sys.stdin.read(1)) if pressed_key == spacebar_key: # 播放动画帧 for frame in frames: print("\033[H\033[J", end="") print(f"加载中: {frame}") time.sleep(0.2) # 清空输入缓冲区:读取所有缓冲的按键并丢弃 while select.select([sys.stdin], [], [], 0)[0]: sys.stdin.read(1) # 按q键退出程序 elif pressed_key == ord('q'): running = False # 这里可以添加其他游戏逻辑 finally: # 恢复终端原始配置 import termios old_term_settings = termios.tcgetattr(sys.stdin) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_term_settings)
方案对比
- 方案一:彻底屏蔽动画期间的输入,适合需要用户专注观看动画的场景,不会产生任何缓冲输入。
- 方案二:允许用户在动画期间按键,但所有按键都会被丢弃,适合不想限制用户操作但又不需要处理动画期间输入的场景。
内容的提问来源于stack exchange,提问作者Alex L
相关产品推荐
相关产品推荐

