如何在Gnome终端中用Python实现无curses库的@字符左右移动?
无需curses库实现Gnome终端中@字符的左右移动
可以利用终端ANSI转义序列控制光标位置和内容显示,结合termios模块修改终端输入模式,实现无需curses库的字符移动功能。以下是具体实现:
核心思路
- 修改终端为原始输入模式:让程序无需等待回车键即可读取单个按键(包括方向键)。
- 使用ANSI转义序列:控制光标移动、覆盖原有字符,实现@的平滑移动。
- 监听方向键的ANSI序列:左箭头对应
\x1b[D,右箭头对应\x1b[C。
完整代码
import sys import termios import tty def get_key(): fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: # 设置终端为原始模式,直接读取按键 tty.setraw(sys.stdin.fileno()) # 方向键是ESC开头的3字节序列,普通字符为1字节 first_char = sys.stdin.read(1) if first_char == '\x1b': key = sys.stdin.read(2) else: key = first_char return key finally: # 恢复终端原有设置,避免影响后续操作 termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) def main(): current_pos = 0 # 初始打印@,强制刷新输出避免缓冲 print('@', end='', flush=True) while True: key = get_key() # 按q键退出程序 if key.lower() == 'q': break # 左箭头处理(仅当位置大于0时允许左移) elif key == '[D': if current_pos > 0: # 光标左移→覆盖原@→再左移→打印新@ sys.stdout.write('\x1b[D \x1b[D@') sys.stdout.flush() current_pos -= 1 # 右箭头处理 elif key == '[C': # 覆盖原@→光标右移→打印新@ sys.stdout.write(' \x1b[C@') sys.stdout.flush() current_pos += 1 # 退出时换行,恢复终端整洁 print() if __name__ == '__main__': main()
代码说明
get_key函数:负责读取按键,区分普通字符和方向键的ANSI序列,操作完成后强制恢复终端原有设置,避免终端状态异常。- 方向键处理:通过ANSI转义序列控制光标移动,配合空格覆盖原有@字符,实现无闪烁的平滑移动效果。
- 强制刷新:每次操作后调用
flush(),确保终端立即显示修改内容,避免输出缓冲导致的延迟。
使用方法:运行程序后,按左/右箭头控制@移动,按q键退出程序。
内容的提问来源于stack exchange,提问作者tuatara
相关产品推荐
相关产品推荐

