Python Curses菜单与Gentoo安装业务函数的整合逻辑问询
Gentoo安装脚本与Curses菜单整合方案
核心原则:分离界面与业务逻辑
完全不用重写现有安装函数,只要把Curses界面交互和安装业务逻辑拆成独立模块:
- 业务函数只负责处理安装流程(磁盘分区、配置写入、系统编译等),只接收参数、返回结果,不涉及任何输入输出操作
- Curses界面层包揽所有用户交互(菜单选择、输入收集、状态展示),调用业务函数时传入参数,再将执行结果反馈给用户
输入处理的替换与整合
之前用input()收集输入的逻辑,确实需要换成Curses的输入方法,但无需修改业务函数本身:
- 单独封装Curses输入组件,替代
input(),收集到输入后再传给业务函数 - 示例代码:
# 纯业务函数(无界面依赖) def set_hostname(hostname): with open("/etc/hostname", "w") as f: f.write(hostname) # Curses输入交互函数 def curses_get_input(stdscr, y, x, prompt): stdscr.addstr(y, x, prompt) stdscr.refresh() curses.echo() # 开启回显让用户看到输入内容 input_str = stdscr.getstr(y, x + len(prompt), 50).decode('utf-8') curses.noecho() return input_str # 界面调用逻辑 def hostname_menu(stdscr): hostname = curses_get_input(stdscr, 5, 2, "请输入主机名: ") set_hostname(hostname) # 调用无界面的业务函数 stdscr.addstr(7, 2, f"主机名已设置为: {hostname}") stdscr.refresh() stdscr.getch() # 等待用户确认后再返回主菜单
菜单与业务流程的联动
用菜单映射表实现完整菜单系统,把每个菜单项和对应的业务处理逻辑绑定:
- 示例代码:
# 菜单选项与对应处理函数的映射 MENU_OPTIONS = [ ("设置主机名", hostname_menu), ("磁盘分区配置", partition_menu), ("开始系统安装", install_system), ("退出安装程序", lambda s: curses.endwin()) ] def main_menu(stdscr): current_row = 0 while True: stdscr.clear() stdscr.addstr(2, 2, "Gentoo 安装助手") # 渲染菜单选项,高亮当前选中项 for idx, (option, _) in enumerate(MENU_OPTIONS): if idx == current_row: stdscr.attron(curses.A_REVERSE) stdscr.addstr(4 + idx, 4, option) stdscr.attroff(curses.A_REVERSE) else: stdscr.addstr(4 + idx, 4, option) stdscr.refresh() # 处理按键输入 key = stdscr.getch() if key == curses.KEY_UP and current_row > 0: current_row -= 1 elif key == curses.KEY_DOWN and current_row < len(MENU_OPTIONS)-1: current_row += 1 elif key == curses.KEY_ENTER or key in [10, 13]: # 调用选中的菜单处理函数,传入Curses窗口对象 MENU_OPTIONS[current_row][1](stdscr)
多文件分离的整合方式
按模块拆分是主流做法,整合逻辑非常清晰:
install_logic.py:存放所有纯业务函数,完全不依赖Cursescurses_ui.py:存放所有Curses界面相关函数(菜单、输入框、提示弹窗),导入install_logic.py调用业务逻辑main.py:程序入口,负责初始化Curses并启动主菜单# main.py import curses from curses_ui import main_menu if __name__ == "__main__": # curses.wrapper会自动处理Curses初始化和异常后的终端恢复 curses.wrapper(main_menu)
关键注意事项
- 执行耗时操作(比如编译软件)时,要在Curses界面实时更新进度:可以给业务函数加回调参数,或者用线程把耗时操作放后台,主线程负责刷新界面
- 所有Curses操作必须在Curses环境中执行,业务函数绝对不能直接调用Curses方法
- 调用外部命令(比如
chroot)或退出前,必须用curses.endwin()恢复终端正常状态,避免终端显示错乱
内容的提问来源于stack exchange,提问作者amadecember
相关产品推荐
相关产品推荐

