如何用CustomTKinter制作Python版CMD风格命令行界面(CLI)?
用CustomTKinter实现CMD风格的命令行界面
用CTkTextbox改造出CMD风格的CLI,核心是控制输入区域仅在最后一行,捕获回车事件处理命令,以下是具体实现方案:
核心思路
- 用CTkTextbox同时承担输出展示和输入载体的作用
- 限制用户只能在最后一行的提示符后输入内容
- 捕获回车事件,提取输入命令、执行对应逻辑后输出结果,再重置输入提示符
完整实现代码
import customtkinter as ctk class CMDInterface(ctk.CTk): def __init__(self): super().__init__() self.title("Custom CMD") self.geometry("800x600") # 初始化文本框 self.textbox = ctk.CTkTextbox(self, wrap="word") self.textbox.pack(fill="both", expand=True, padx=10, pady=10) self.textbox.configure(state="normal") # 设置初始提示符 self.prompt = "C:\\> " self.textbox.insert("end", self.prompt) self.textbox.configure(state="disabled") # 绑定回车事件 self.textbox.bind("<Return>", self.handle_command) # 绑定键盘输入,确保光标始终在可输入区域 self.textbox.bind("<Key>", self.restrict_cursor) def restrict_cursor(self, event): # 禁止修改提示符及之前的历史内容 current_cursor = self.textbox.index("insert") prompt_start = self.textbox.index(f"end-{len(self.prompt)+1}c") # 光标在提示符前时,强制移到末尾 if current_cursor < prompt_start: self.textbox.see("end") self.textbox.mark_set("insert", "end") return "break" # 禁止退格删除提示符 if event.keysym == "BackSpace": if self.textbox.index("insert") == prompt_start: return "break" return None def handle_command(self, event): # 阻止默认换行行为 event.widget.configure(state="normal") # 提取用户输入的命令内容 command_start = self.textbox.index(f"end-{len(self.prompt)+1}c") command = self.textbox.get(command_start, "end-1c").strip() # 添加换行分隔输入与输出 self.textbox.insert("end", "\n") # 执行命令处理逻辑 output = self.process_command(command) # 输出处理结果 if output: self.textbox.insert("end", f"{output}\n") # 添加新的输入提示符 self.textbox.insert("end", self.prompt) # 自动滚动到末尾 self.textbox.see("end") event.widget.configure(state="disabled") return "break" def process_command(self, command): # 自定义命令处理逻辑,可按需扩展 if not command: return "" elif command.lower() == "dir": return " Volume in drive C has no label.\n Volume Serial Number is XXXX-XXXX\n\n Directory of C:\\\n\n01/01/2024 12:00 AM <DIR> Users\n01/01/2024 12:00 AM <DIR> Program Files\n 0 File(s) 0 bytes\n 2 Dir(s) 100,000,000,000 bytes free" elif command.lower().startswith("echo "): return command[5:] elif command.lower() == "exit": self.quit() return "" else: return f"'{command}' 不是内部或外部命令,也不是可运行的程序或批处理文件。" if __name__ == "__main__": ctk.set_appearance_mode("dark") # 深色模式更贴近原生CMD风格 ctk.set_default_color_theme("blue") app = CMDInterface() app.mainloop()
关键细节说明
- 光标限制:通过
restrict_cursor函数锁定可输入区域,避免用户误修改历史输出内容 - 回车处理:
handle_command函数接管回车事件,完成命令提取、执行、结果输出的全流程 - 命令扩展:在
process_command函数中可添加任意自定义命令逻辑,比如调用系统命令、执行Python函数等
内容的提问来源于stack exchange,提问作者Seb
相关产品推荐
相关产品推荐

