正常运行了
This commit is contained in:
+40
-35
@@ -11,6 +11,9 @@
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#define DBG_TAG "[UI_MENU]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/* 菜单节点表(简化自 DTU-HMI menuTab):层级 + 名称 */
|
||||
typedef struct {
|
||||
uint8_t level; /* 0=根页面, 1..3=子层次 */
|
||||
@@ -87,9 +90,9 @@ static const ui_menu_node_t g_menu_tab[] = {
|
||||
* 入口参数:无
|
||||
* 返回值:0 - 成功,其他 - 失败(对象创建失败)
|
||||
* 限定条件:ui_port_init() 已成功调用,活动屏幕存在
|
||||
* 函数说明:1. 依据紧凑节点表按层级生成 lv_menu 页面与返回栈
|
||||
* 2. 将菜单对象加入默认输入组,支持远端按键导航
|
||||
* 3. 叶子节点挂占位页,等待后续逐项填充具体功能
|
||||
* 函数说明:1. 仅构建主页面(根页 + 一级菜单项),子树暂不构建以控制内存占用
|
||||
* 2. 文本全部使用静态字符串(不 strdup),减少 LVGL 堆分配
|
||||
* 3. 构建中监控 LVGL 池空闲内存,不足时中止而非崩溃
|
||||
*/
|
||||
int ui_menu_init(void)
|
||||
{
|
||||
@@ -101,44 +104,46 @@ int ui_menu_init(void)
|
||||
lv_menu_set_mode_root_back_button(menu, LV_MENU_ROOT_BACK_BUTTON_ENABLED);
|
||||
lv_group_add_obj(lv_group_get_default(), menu);
|
||||
|
||||
/* 仅构建主页面:根页 + 一级菜单项(静态文本,不建子树,省内存) */
|
||||
lv_obj_t *root_page = lv_menu_page_create(menu, NULL);
|
||||
if (root_page == NULL) {
|
||||
return -1;
|
||||
}
|
||||
lv_menu_set_page_title_static(root_page, "主界面");
|
||||
|
||||
lv_mem_monitor_t mon;
|
||||
lv_mem_monitor(&mon);
|
||||
DBG_INFO("menu build start: total=%u free=%u big=%u",
|
||||
(unsigned)mon.total_size,
|
||||
(unsigned)mon.free_size, (unsigned)mon.free_biggest_size);
|
||||
|
||||
uint32_t n = sizeof(g_menu_tab) / sizeof(g_menu_tab[0]);
|
||||
lv_obj_t *root_page = NULL;
|
||||
lv_obj_t *parent_stack[4] = {NULL, NULL, NULL, NULL};
|
||||
for (uint32_t i = 1; i < n; i++) {
|
||||
if (g_menu_tab[i].level != 1) {
|
||||
continue; /* 只显示一级菜单项,子树暂不构建 */
|
||||
}
|
||||
|
||||
/* 内存警戒:空闲池不足则中止,避免 LVGL 内部 NULL 解引用崩溃 */
|
||||
lv_mem_monitor(&mon);
|
||||
if (mon.free_biggest_size < 1024) {
|
||||
DBG_ERROR("menu mem low: abort at item %u (free=%u big=%u)",
|
||||
(unsigned)i, (unsigned)mon.free_size,
|
||||
(unsigned)mon.free_biggest_size);
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
uint8_t L = g_menu_tab[i].level;
|
||||
const char *name = g_menu_tab[i].name;
|
||||
|
||||
if (i == 0) {
|
||||
/* 第 0 节点为根(主界面) */
|
||||
root_page = lv_menu_page_create(menu, name);
|
||||
parent_stack[0] = root_page;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 当前节点页面 */
|
||||
lv_obj_t *page = lv_menu_page_create(menu, name);
|
||||
|
||||
/* 叶子:页内挂占位内容 */
|
||||
int leaf = (i + 1 >= n) || (g_menu_tab[i + 1].level <= L);
|
||||
if (leaf) {
|
||||
lv_obj_t *ph = lv_menu_cont_create(page);
|
||||
lv_obj_t *pl = lv_label_create(ph);
|
||||
lv_label_set_text(pl, "功能未实现(占位)");
|
||||
}
|
||||
|
||||
/* 挂到父页:level0 直挂根,其余挂到上一级页面 */
|
||||
lv_obj_t *parent = (L == 0) ? root_page : parent_stack[L - 1];
|
||||
|
||||
/* 在父页创建一个容器项,点击加载当前页 */
|
||||
lv_obj_t *item = lv_menu_cont_create(parent);
|
||||
lv_obj_t *item = lv_menu_cont_create(root_page);
|
||||
lv_obj_t *lbl = lv_label_create(item);
|
||||
lv_label_set_text(lbl, name);
|
||||
lv_menu_set_load_page_event(menu, item, page);
|
||||
|
||||
parent_stack[L] = page;
|
||||
lv_label_set_text_static(lbl, name);
|
||||
}
|
||||
|
||||
lv_menu_set_page(menu, root_page);
|
||||
|
||||
lv_mem_monitor(&mon);
|
||||
DBG_INFO("menu build done: total=%u free=%u big=%u used=%u",
|
||||
(unsigned)mon.total_size,
|
||||
(unsigned)mon.free_size, (unsigned)mon.free_biggest_size,
|
||||
(unsigned)(mon.total_size - mon.free_size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user