OpenWRT环境下基于luaposix的curses文本UI开发示例求助
luaposix实现OpenWRT平台curses文本菜单方案
适配说明
- 运行环境完全匹配需求:OpenWRT内置Lua 5.1.5、opkg源官方luaposix 35.1.1版本,无任何额外第三方依赖
- 所有curses能力直接调用luaposix内置的curses模块,不需要单独安装ncurses的其他Lua绑定
- 内置终端状态还原逻辑,避免程序异常退出后终端显示错乱
最小可运行示例代码
-- 适配Lua 5.1 + luaposix 35.1.1 无额外依赖 local curses = require "posix.curses" -- 菜单配置 local menu_items = { "查看系统信息", "查看网络状态", "重启设备", "退出菜单" } local selected = 1 local stdscr -- 安全退出,保证终端状态还原 local function safe_exit(code) if stdscr then curses.echo() curses.nocbreak() stdscr:keypad(false) stdscr:endwin() end os.exit(code or 0) end -- 初始化curses环境 local function init_curses() stdscr = curses.initscr() if not stdscr then io.stderr:write("当前终端不支持curses模式\n") os.exit(1) end -- 异常捕获,任何报错都先还原终端 local ok = pcall(function() curses.cbreak() curses.noecho() stdscr:keypad(true) stdscr:clear() end) if not ok then safe_exit(1) end end -- 绘制菜单界面 local function draw_menu() stdscr:clear() -- 绘制边框 stdscr:border(0,0,0,0,0,0,0,0) -- 绘制标题 local title = " OpenWRT 操作菜单 " stdscr:mvaddstr(1, (curses.cols() - #title)/2, title) -- 绘制菜单项 local start_y = 4 for i, item in ipairs(menu_items) do local prefix = " " if i == selected then prefix = "> " -- 选中项加反显高亮 stdscr:attron(curses.A_REVERSE) end stdscr:mvaddstr(start_y + i -1, 10, prefix .. item) if i == selected then stdscr:attroff(curses.A_REVERSE) end end -- 绘制底部提示 local tip = " 方向键选择 | 回车确认 | q退出 " stdscr:mvaddstr(curses.lines()-2, (curses.cols() - #tip)/2, tip) -- 刷新显示 stdscr:refresh() end -- 主逻辑循环 local function main_loop() while true do draw_menu() local key = stdscr:getch() if key == string.byte('q') then break elseif key == curses.KEY_UP then selected = selected -1 if selected < 1 then selected = #menu_items end elseif key == curses.KEY_DOWN then selected = selected +1 if selected > #menu_items then selected = 1 end elseif key == 10 then -- 回车键 stdscr:clear() stdscr:border(0,0,0,0,0,0,0,0) local tip = "你选中了选项:" .. menu_items[selected] .. ",按任意键返回" stdscr:mvaddstr(curses.lines()/2, (curses.cols() - #tip)/2, tip) stdscr:refresh() stdscr:getch() -- 选中最后一个退出项直接退出 if selected == #menu_items then break end end end end -- 程序入口 init_curses() local ok, err = pcall(main_loop) if not ok then io.stderr:write("运行错误:" .. tostring(err) .. "\n") end safe_exit(0)
核心接口入门参考(对应luaposix 35.1.1版本)
luaposix的curses是对标准ncurses C接口的轻量封装,接口命名、常量定义和C版本完全一致,不需要专门查找luaposix专属教程,对照ncurses基础开发逻辑调整为Lua语法即可,常用接口如下:
- 初始化与清理
curses.initscr():初始化curses环境,返回主窗口对象stdscr:endwin():退出前必须调用,还原终端默认状态
- 输入模式配置
curses.cbreak():禁用行缓冲,用户按键后立即返回不需要等回车curses.noecho():关闭用户输入的自动回显stdscr:keypad(true):启用功能键识别,支持方向键、翻页键等特殊按键
- 绘制操作
stdscr:clear():清空整个窗口内容stdscr:mvaddstr(y, x, 文本):移动光标到(y,x)坐标位置打印文本,坐标以窗口左上角为(0,0)原点,y轴向下递增stdscr:attron(属性常量)/stdscr:attroff(属性常量):开启/关闭文本显示属性,常用属性包括curses.A_REVERSE(反显高亮)、curses.A_BOLD(粗体)stdscr:border():绘制窗口边框stdscr:refresh():所有绘制操作完成后必须调用,才会把内容实际渲染到终端
- 输入获取
stdscr:getch():阻塞等待用户按键,返回按键对应数值;方向键对应常量为curses.KEY_UP、curses.KEY_DOWN,回车键对应数值10,普通字符键对应string.byte('字符')的返回值
注意:如果需要适配不同尺寸的终端,可通过
curses.lines()获取终端当前行数,curses.cols()获取终端当前列数,动态调整元素绘制位置。
OpenWRT部署运行步骤
- 安装官方源依赖:执行
opkg update && opkg install luaposix - 将示例代码保存为
text_menu.lua,上传到OpenWRT设备可写目录 - 执行
lua text_menu.lua即可启动菜单,操作逻辑为:上下方向键切换选项,回车确认选择,按q键退出
内容的提问来源于stack exchange,提问作者Sina S.
相关产品推荐
相关产品推荐

