28. 菜单部件
一、菜单部件
菜单小部件可轻松创建多级菜单。命令、子菜单或者分隔条都可包括在菜单之中。每一个创建的菜单至多有四级子菜单。菜单部件是一组通常在功能上相关的命令或部件的容器。提供特殊的布局行为,并支持用户启动的工具栏大小调整和排列。
菜单小部件是由两个大类构建而成,第一个大类为 主容器,第二个大类为 侧边栏容器,它们各自也是由不同的部分构建而成的,菜单部件示意图来如下图所示:
LVGL 提供给用户的菜单部件相关函数。
lv_obj_t * lv_menu_create(lv_obj_t * parent); // 创建菜单部件
lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title); // 创建菜单页面
lv_obj_t * lv_menu_cont_create(lv_obj_t * parent); // 创建菜单容器
lv_obj_t * lv_menu_section_create(lv_obj_t * parent); // 创建空区域
lv_obj_t * lv_menu_separator_create(lv_obj_t * parent); // 创建分隔符
void lv_menu_set_page(lv_obj_t * obj, lv_obj_t * page); // 设置菜单页面为主容器
void lv_menu_set_sidebar_page(lv_obj_t * obj, lv_obj_t * page); // 设置菜单页面为侧边栏容器
void lv_menu_set_mode_header(lv_obj_t * obj, lv_menu_mode_header_t mode); // 设置标题模式
void lv_menu_set_mode_root_back_button(lv_obj_t * obj, lv_menu_mode_root_back_button_t mode); // 设置根返回按键
void lv_menu_set_load_page_event(lv_obj_t * menu, lv_obj_t * obj, lv_obj_t * page); // 菜单页面连接
lv_obj_t * lv_menu_get_cur_main_page(lv_obj_t * obj); // 返回指向当前在main中显示的菜单页的指针
lv_obj_t * lv_menu_get_cur_sidebar_page(lv_obj_t * obj); // 返回指向当前在侧边栏中显示的菜单页的指针
lv_obj_t * lv_menu_get_main_header(lv_obj_t * obj); // 获取主标题
lv_obj_t * lv_menu_get_main_header_back_button(lv_obj_t * obj); // 获取主标题返回按键
lv_obj_t * lv_menu_get_sidebar_header(lv_obj_t * obj); // 获取侧边栏标题
lv_obj_t * lv_menu_get_sidebar_header_back_button(lv_obj_t * obj); // 获取侧边栏返回按键
bool lv_menu_back_button_is_root(lv_obj_t * menu, lv_obj_t * obj); // 设置返回根按键
void lv_menu_clear_history(lv_obj_t * obj); // 清除菜单
我们只需调用 lv_menu_create()
函数就可以 创建菜单部件。一开始创建菜单部件时,它只包含主容器和根返回按键,如下图所示:
/**
* @brief 创建菜单部件
*
* @param parent 指向父部件的指针
* @return lv_obj_t* 指向菜单部件的指针
*/
lv_obj_t * lv_menu_create(lv_obj_t * parent);
菜单部件创建时,它只单单创建主容器以及根返回按键,其它部分需由用户自己添加。
标题模式可以设置在表头标题和侧边栏标题,用户可调用函数 lv_menu_set_mode_header()
函数 设置它们的标题模式。
/**
* @brief 设置标题模式
*
* @param obj 指向菜单部件的指针
* @param mode 标题模式
*/
void lv_menu_set_mode_header(lv_obj_t * obj, lv_menu_mode_header_t mode);
标题模式具有三种类型,这些类型如下所示:
enum _lv_menu_mode_header_t {
LV_MENU_HEADER_TOP_FIXED, // 标题位于顶部
LV_MENU_HEADER_TOP_UNFIXED, // 标题位于顶部,可以滚动出视图
LV_MENU_HEADER_BOTTOM_FIXED // 标题位于底部
};
用户可调用 lv_menu_set_mode_root_back_button()
函数 设置根返回按钮模式。默认情况下,这个根按键是启用的。
/**
* @brief 设置根返回按键
*
* @param obj 指向菜单部件的指针
* @param mode 根返回按钮模式
*/
void lv_menu_set_mode_root_back_button(lv_obj_t * obj, lv_menu_mode_root_back_button_t mode);
其中,根返回按钮模式的可选值如下:
enum _lv_menu_mode_root_back_button_t {
LV_MENU_ROOT_BACK_BUTTON_DISABLED, // 菜单根按键禁用
LV_MENU_ROOT_BACK_BUTTON_ENABLED // 菜单根按键启用
};
我们可以向该页面添加任何小部件,创建新的菜单页面 的函数是 lv_menu_page_create()
。
/**
* @brief 创建菜单页面
*
* @param parent 指向菜单部件的指针
* @param title 标题文本内容
* @return lv_obj_t* 执行菜单页面的指针
*/
lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title);
创建菜单页面之后,用户可以使用 lv_menu_set_page()
函数将其 设置为主要区域。
/**
* @brief 设置菜单页面为主容器
*
* @param obj 指向菜单部件的指针
* @param page 指向菜单页面的指针,如果为NULL,则用来清除主菜单和清除菜单历史
*/
void lv_menu_set_page(lv_obj_t * obj, lv_obj_t * page);
创建菜单页面之后,用户可以使用 lv_menu_set_sidebar_page()
函数将其 设置到侧边栏。
/**
* @brief 设置菜单页面为侧边栏容器
*
* @param obj 指向菜单部件的指针
* @param page 指向菜单页面的指针,如果为NULL,则用来清除侧边栏
*/
void lv_menu_set_sidebar_page(lv_obj_t * obj, lv_obj_t * page);
菜单页面的连接是指我们在页面上创建了一个可点击的对象,我们希望点击该对象之后系统自动打开我们已经创建好的页面,这叫做 菜单页面的连接,这个操作类似于界面切换原理。菜单页面连接的使用可调用 lv_menu_set_load_page_event()
函数设置连接关系。
/**
* @brief 菜单页面连接
*
* @param menu 指向菜单部件的指针
* @param obj 表示连接源,即点击对象
* @param page 指向连接的页面
*/
void lv_menu_set_load_page_event(lv_obj_t * menu, lv_obj_t * obj, lv_obj_t * page);
二、实验例程
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
int main(void)
{
HAL_Init();
System_Clock_Init(8, 336, 2, 7);
Delay_Init(168);
SPI_Simulate_Init();
// SRAM_Init();
TIM_Base_Init(&g_tim6_handle, TIM6, 83, 999);
__HAL_TIM_CLEAR_IT(&g_tim6_handle, TIM_IT_UPDATE); // 清除更新中断标志位
HAL_TIM_Base_Start_IT(&g_tim6_handle); // 使能更新中断,并启动计数器
lv_init();
lv_port_disp_init();
lv_port_indev_init();
// 测试代码
lv_obj_t *menu = lv_menu_create(lv_scr_act()); // 创建菜单部件
lv_obj_center(menu); // 菜单部件居中对齐
lv_obj_t *main_page = lv_menu_page_create(menu, "Main"); // 创建菜单页面
lv_menu_set_page(menu, main_page); // 设置主容器页面
lv_obj_t *sidebar_page = lv_menu_page_create(menu, "Sidebar"); // 创建菜单页面
lv_menu_set_sidebar_page(menu, sidebar_page); // 设置侧边栏页面
lv_obj_t *page1 = lv_menu_page_create(menu, "Page1"); // 创建菜单页面
lv_menu_set_page(menu, page1);
lv_obj_t *label1 = lv_label_create(page1);
lv_label_set_text(label1, "Page1");
lv_obj_center(label1);
lv_obj_set_style_text_font(label1, &lv_font_montserrat_30, LV_PART_MAIN);
lv_obj_t *button1 = lv_btn_create(sidebar_page);
lv_obj_set_height(button1, 20);
lv_menu_set_load_page_event(menu, button1, page1); // 设置菜单页面的连接
lv_obj_t *page2 = lv_menu_page_create(menu, "Page2"); // 创建菜单页面
lv_menu_set_page(menu, page2);
lv_obj_t *label2 = lv_label_create(page2);
lv_label_set_text(label2, "Page2");
lv_obj_center(label2);
lv_obj_set_style_text_font(label2, &lv_font_montserrat_30, LV_PART_MAIN);
lv_obj_t *button2 = lv_btn_create(sidebar_page);
lv_obj_set_height(button2, 20);
lv_menu_set_load_page_event(menu, button2, page2); // 设置菜单页面的连接
while (1)
{
lv_timer_handler();
Delay_ms(5);
}
return 0;
}