Python CLI WebSocket聊天应用输入框重置问题求助
解决CLI聊天应用输入框被清空的问题
核心思路
问题的关键在于实时捕获用户未完成的输入内容,并在屏幕重绘时将其恢复到输入框中。你观察到的“按下回车仍能发送之前内容”的现象,说明输入确实被保存在缓冲区里,我们可以通过手动管理输入流来获取并复用这部分内容。
修改方案
我们需要:
- 维护一个变量跟踪用户当前的输入内容
- 手动处理输入流(替代
aioconsole.ainput),实时更新输入内容 - 屏幕重绘时,将保存的输入内容回填到输入框
修改后的代码
import sys import asyncio import aioconsole chat = [] current_input = "" # 保存用户正在输入的内容 async def start(): send_task = asyncio.create_task(send()) receive_task = asyncio.create_task(receive_simulator()) await asyncio.gather(send_task, receive_task) async def send(): global current_input stdin, _ = aioconsole.get_standard_streams() while True: # 绘制输入提示和当前输入 sys.stdout.write(f"\rType message: {current_input}") sys.stdout.flush() # 读取单个字符 char = await stdin.read(1) char = char.decode('utf-8') if char == '\n': # 用户按下回车,发送消息 if current_input.strip(): receive(current_input) current_input = "" sys.stdout.write("\n") elif char == '\x7f': # 处理退格键 if current_input: current_input = current_input[:-1] else: # 普通字符,添加到当前输入 current_input += char def receive(message, sim=False): chat.append(message) reset_chat_screen() # 模拟收到新消息 async def receive_simulator(): await asyncio.sleep(3) receive("Incoming message from server", sim=True) await asyncio.sleep(5) receive("Another test message", sim=True) def reset_chat_screen(): # 清空屏幕并将光标移回左上角 sys.stdout.write(chr(27) + "[2J") sys.stdout.write(chr(27) + "[H") # 打印所有聊天消息 for msg in chat: print(f"Message: {msg}") print() # 空行分隔聊天区和输入区 # 恢复输入提示和当前输入内容 sys.stdout.write(f"Type message: {current_input}") sys.stdout.flush() if __name__ == "__main__": asyncio.run(start())
关键部分解释
current_input变量:全局保存用户正在输入的每一个字符,确保屏幕重绘时能找回未完成的内容。- 手动处理输入流:通过
aioconsole.get_standard_streams()获取标准输入流,逐字符读取输入,实时更新current_input,同时处理退格、回车等特殊按键。 - 屏幕重绘逻辑:清空屏幕后,先打印所有聊天消息,再将
current_input回填到输入提示后,确保用户的输入不会丢失。
这样修改后,当新消息到来时,屏幕会重绘聊天内容,同时输入框会保留用户正在输入的内容,完全符合你的期望行为。
内容的提问来源于stack exchange,提问作者O'Niel
相关产品推荐
相关产品推荐

