解码LVGL基础
LVGL9.2 源码结构
LVGL9.2 源码按功能模块化划分,核心目录及文件的详细作用如下:
| 路径 | 核心文件 / 子目录 | 功能说明 |
|---|---|---|
/ |
CMakeLists.txt |
顶层编译配置文件,控制整个工程的编译规则: - 可指定编译类型(静态库 STATIC/ 动态库SHARED);- 配置编译器选项(如 -O3 优化、-Wall 警告检查);- 关联子目录(如 lvgl/、lv_drivers/)的编译。 |
/ |
lv_conf.h |
LVGL 全局配置文件,决定控件启用、内存大小、显示特性: - 启用核心控件(如 LV_USE_BTN按钮、LV_USE_LABEL标签);- 设置显示参数(如 LV_HOR_RES_MAX屏幕宽度、LV_VER_RES_MAX屏幕高度);- 配置内存池大小(如 LV_MEM_SIZE,默认 32KB)。 |
/lvgl |
demos/ |
官方综合案例,覆盖复杂 UI 场景: - 如 lv_demo_widgets():展示所有基础控件的组合使用;- 如 lv_demo_benchmark():测试 LVGL 渲染性能(帧率、内存占用);- 案例可直接调用,快速验证硬件兼容性。 |
/lvgl |
examples/ |
基础功能示例,按模块分类: - anim/:动画示例(如lv_example_anim_1()实现控件平移);- event/:事件示例(如按钮单击、滑动条数值变化);- layouts/:布局示例(如弹性布局、网格布局);- libs/:第三方库示例(FFmpeg 音视频、FreeType 字体)。 |
/lvgl/env_support/ |
平台支持配置文件 | 适配不同硬件 / 系统的 “桥梁”: - esp/:ESP32/ESP8266 平台配置(如 GPIO 映射、SPI 屏幕驱动);- rtthread/:RT-Thread 实时系统适配(线程创建、定时器绑定);- zephyr/:Zephyr 操作系统适配(设备树集成、驱动注册);- cmake/custom.cmake:控制 LVGL 库编译形态(动态库 / 静态库),可自定义编译选项。 |
/lvgl/src |
core/ |
LVGL 核心模块,决定对象、事件、样式的底层实现: - lv_obj.c:基础对象lv_obj_t的创建、删除、属性设置(如位置、大小);- lv_event.c:事件系统(绑定、触发、冒泡);- lv_style.c:样式系统(属性设置、状态管理);- lv_obj_tree.c:对象树管理(父子关系维护、内存递归释放)。 |
/lvgl/src |
display/ |
显示控制核心,负责屏幕数据输出: - lv_display.c:屏幕初始化(分辨率设置、刷新回调注册);- lv_draw.c:绘图 API(点、线、矩形、文本绘制);- lv_buf.c:显示缓冲区管理(双缓冲 / 单缓冲配置,避免屏幕闪烁)。 |
/lvgl/src |
osal/ |
操作系统抽象层,解耦 LVGL 与具体 OS: - 提供通用接口: lv_thread_create()(创建线程)、lv_mutex_lock()(互斥锁)、lv_timer_create()(定时器);- 无 OS 场景(如裸机):提供 lv_os_alrtos.c适配,模拟线程与定时器。 |
/lvgl/src |
widgets/ |
所有控件的实现目录,每个控件对应独立.c文件:- lv_btn.c:按钮控件(单击、长按、禁用状态);- lv_label.c:标签控件(文本设置、对齐、换行);- lv_img.c:图像控件(RGB 数据显示、文件加载);- lv_textarea.c:输入框控件(文本输入、密码模式、光标管理)。 |
运行官方案例
调用lv_example_anim_1()实现动画案例,完整代码(含 LVGL 初始化、显示 / 输入设备适配):
函数分析:
/**
* 获取当前活跃的顶层屏幕对象
* @return 当前活跃的顶层屏幕对象指针(lv_obj_t*),作为控件的父对象
* @note LVGL中所有控件需依赖父对象显示,顶层屏幕是最顶层的容器对象;
* 若没有活跃屏幕,可能返回NULL,需确保调用前已初始化屏幕系统
*/
lv_obj_t * lv_screen_active(void);
/**
* 创建标签控件
* @param parent 父对象指针(lv_obj_t*),标签将依附于该父对象显示
* @return 新创建的标签控件对象指针(lv_obj_t*),用于后续操作标签
* @note 标签是LVGL中用于显示文本的基础控件;
* 需通过其他接口(如lv_label_set_text)设置显示内容后才会呈现文本
*/
lv_obj_t * lv_label_create(lv_obj_t * parent);
/**
* 设置标签控件的显示文本
* @param label 标签对象指针(lv_obj_t*),需为已创建的标签控件
* @param text 待显示的文本字符串(const char*),支持ASCII字符
* @return 无返回值(void)
* @note 若需显示中文/特殊字符,需提前配置对应字库,否则可能显示乱码;
* 文本内容会覆盖标签原有的显示内容
*/
void lv_label_set_text(lv_obj_t * label, const char * text);
/**
* 设置对象在父对象中的位置
* @param obj 目标对象指针(lv_obj_t*),可为任意LVGL控件
* @param x X轴坐标(int32_t),相对于父对象左上角的水平偏移量(向右为正)
* @param y Y轴坐标(int32_t),相对于父对象左上角的垂直偏移量(向下为正)
* @return 无返回值(void)
* @note 坐标原点为父对象左上角;
* 该函数会覆盖对象之前的布局设置(如居中、对齐等)
*/
void lv_obj_set_pos(lv_obj_t * obj, int32_t x, int32_t y);
/**
* 创建开关控件
* @param parent 父对象指针(lv_obj_t*),开关将依附于该父对象显示
* @return 新创建的开关控件对象指针(lv_obj_t*),用于后续操作开关
* @note 开关是二态交互控件,支持选中(LV_STATE_CHECKED)和未选中状态;
* 态变化可通过LV_EVENT_VALUE_CHANGED事件捕获
*/
lv_obj_t * lv_switch_create(lv_obj_t * parent);
/**
* 使对象在父对象中居中显示
* @param obj 目标对象指针(lv_obj_t*),可为任意LVGL控件
* @return 无返回值(void)
* @note 同时实现水平和垂直方向居中,无需手动计算坐标;
* 父对象大小变化时,对象会自动保持居中(需开启布局更新机制)
*/
void lv_obj_center(lv_obj_t * obj);
/**
* 为对象添加状态标记
* @param obj 目标对象指针(lv_obj_t*),可为任意LVGL控件
* @param state 状态标记(lv_state_t),如LV_STATE_CHECKED(选中)、LV_STATE_DISABLED(禁用)等
* @return 无返回值(void)
* @note 状态会影响控件的外观(如开关选中时的滑块位置、颜色);
* 可通过lv_obj_clear_state移除状态
*/
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
/**
* 为对象绑定事件回调函数
* @param obj 目标对象指针(lv_obj_t*),事件源对象
* @param cb(callback) 回调函数指针(lv_event_cb_t),事件触发时执行的函数
* @param event 事件类型(lv_event_t),如LV_EVENT_VALUE_CHANGED(值变化)、LV_EVENT_CLICKED(点击)等
* @param user_data 用户数据(void*),传递给回调函数的自定义数据(如关联的其他控件)
* @return 无返回值(void)
* @note 同一对象可绑定多个不同类型的事件,或同一事件绑定多个回调;
* 回调函数中可通过lv_event_get_target()获取事件源,lv_event_get_user_data()获取用户数据
*/
void lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t cb, lv_event_t event, void * user_data);

/**
* LVGL动画示例函数:创建标签与开关控件,通过开关状态变化触发标签动画(需配合回调函数实现完整动画逻辑)
*/
void lv_example_anim_1(void)
{
/* 创建标签控件:创建对象时需指定父对象,此处父对象为当前活跃的顶层屏幕,所有控件需依赖父对象完成显示
* 标签是常用基础控件,主要用于显示文本类信息,需绑定到父对象后才能在界面上呈现
*/
lv_obj_t * label = lv_label_create(lv_screen_active());
/* 设置标签文本内容:标签控件通过该接口定义显示的具体文本,支持英文、数字等基础字符
* 若需显示中文,需额外配置对应的中文字库,确保文本能正常渲染不出现乱码
*/
lv_label_set_text(label, "Hello animations!");
/* 设置标签位置:通过指定X、Y坐标控制对象在父对象中的显示位置,坐标原点为父对象左上角
* 此处X=100像素、Y=10像素,意味着标签从屏幕左上角向右偏移100像素、向下偏移10像素显示
*/
lv_obj_set_pos(label, 100, 10);
/* 创建开关控件:开关是具有二态(选中/未选中)的交互控件,可用于触发状态相关的逻辑
* 同样需指定父对象为当前活跃屏幕,确保与标签在同一界面层级显示
*/
lv_obj_t * sw = lv_switch_create(lv_screen_active());
/* 开关居中显示:通过简化的居中接口,让开关在父对象(屏幕)中水平和垂直方向均居中
* 无需手动计算坐标,直接通过对齐逻辑实现控件在父对象内的居中布局
*/
lv_obj_center(sw);
/* 设置开关为选中状态:控件存在多种状态(如默认、选中、禁用等),此接口为开关添加选中状态
* 选中状态下,开关会呈现预设的开启样式(如滑块滑动到一侧、背景色变化等),与未选中状态形成视觉区分
*/
lv_obj_add_state(sw, LV_STATE_CHECKED);
/* 为开关绑定数值变化事件:当开关状态(选中/未选中)发生改变时,触发指定的回调函数
* 同时将标签控件作为用户数据传递给回调,便于在回调中操作标签(如控制标签动画)
* 事件触发的核心逻辑需在回调函数(sw_event_cb)中实现,此处仅完成事件与对象的绑定
*/
lv_obj_add_event_cb(sw, sw_event_cb, LV_EVENT_VALUE_CHANGED, label);
}
效果

LVGL对象模型
LVGL 用 C 语言模拟面向对象思想,核心是lv_obj_t基础对象。

核心概念:基类与子类
- 基类(lv_obj_t):所有控件的 “父类”,定义通用属性(位置、大小、样式、父子关系)和行为(创建、删除)。
- 子类(控件):如按钮(
lv_btn_t)、标签(lv_label_t),继承lv_obj_t的所有属性,同时扩展自身特性(自身属性依赖宏的条件编译实现):- 按钮:新增 “按下状态”“点击事件”;
- 标签:新增 “文本内容”“字体样式”;
- 所有子类创建时需指定父对象(如
lv_btn_create(parent)),父对象可为lv_scr_act()(当前活跃屏幕)或其他控件。
父子对象关系
lv_obj_t (类)定义了控件的抽象特点,其定义包含了数据的形式以及对数据的操作。控件(子类)比原本的类(称为父类或基类)要更加具体化,子类会继承父类的属性和行为。定义一个对象时,可以给这个对象指定它的父对象。
视觉关系:子对象受父对象约束
标签左半部分移出屏幕,超出部分不可见(默认裁剪)
图示:

视觉关系:子对象跟随父对象移动
父对象可拖拽,子对象同步移动
图示:

内存关系:删除父对象,子对象自动释放
“父对象管理子对象内存”
图示:

基础对象常用接口
基础控件创建
/**
* 创建按钮控件(基础交互控件,支持单击、长按等事件)
* @param parent 父对象指针(lv_obj_t*,不可为NULL,控件将挂载到该父对象下)
* @return 新创建的按钮对象指针(lv_obj_t*),创建失败返回NULL
* @note 按钮默认无文本,需通过创建 lv_label_t 子对象添加文本;
* 默认支持按下视觉反馈,可通过 lv_obj_add_event_cb() 绑定 LV_EVENT_CLICKED 等事件
*/
lv_obj_t * lv_button_create(lv_obj_t * parent);
/**
* 创建标签控件(用于显示文本,支持换行、对齐、样式修改)
* @param parent 父对象指针(lv_obj_t*,不可为NULL)
* @return 新创建的标签对象指针(lv_obj_t*),创建失败返回NULL
* @note 标签默认无文本,需通过 lv_label_set_text(label, "目标文本") 设置显示内容;
* 支持多行文本(文本含 '\n' 或通过 lv_label_set_long_mode() 设置自动换行);
* 文本颜色、字体等通过 lv_obj_set_style_text_xxx() 接口调整
*/
lv_obj_t * lv_label_create(lv_obj_t * parent);
/**
* 创建文本输入框控件(支持单行/多行文本输入,带光标、滚动功能)
* @param parent 父对象指针(lv_obj_t*,不可为NULL)
* @return 新创建的文本输入框对象指针(lv_obj_t*),创建失败返回NULL
* @note 默认支持多行输入,可通过 lv_textarea_set_one_line(textarea, true) 切换为单行模式;
* 输入内容通过 lv_textarea_get_text(textarea) 获取,通过 lv_textarea_set_text(textarea, "初始值") 设置初始内容;
* 支持输入限制(如字符长度、输入类型),需配合 lv_textarea_set_max_length()、lv_textarea_set_input_mode() 使用
*/
lv_obj_t * lv_textarea_create(lv_obj_t * parent);
/**
* 创建滑动条控件(用于数值选择,支持单滑块、范围选择,可绑定数值变化事件)
* @param parent 父对象指针(lv_obj_t*,不可为NULL)
* @return 新创建的滑动条对象指针(lv_obj_t*),创建失败返回NULL
* @note 默认数值范围为 0~100,可通过 lv_slider_set_range(slider, min, max) 调整;
* 当前数值通过 lv_slider_get_value(slider) 获取,通过 lv_slider_set_value(slider, val, LV_ANIM_ON/OFF) 设置(支持动画开关);
* 数值变化时触发 LV_EVENT_VALUE_CHANGED 事件,需通过 lv_obj_add_event_cb() 绑定回调
*/
lv_obj_t * lv_slider_create(lv_obj_t * parent);
/**
* 创建复选框控件(用于二选一状态切换,支持勾选/未勾选视觉反馈)
* @param parent 父对象指针(lv_obj_t*,不可为NULL)
* @return 新创建的复选框对象指针(lv_obj_t*),创建失败返回NULL
* @note 默认无文本,需通过 lv_checkbox_set_text(checkbox, "选项文本") 添加文本;
* 勾选状态通过 lv_checkbox_is_checked(checkbox) 判断(返回 bool),通过 lv_checkbox_set_checked(checkbox, true/false) 设置;
* 状态变化时触发 LV_EVENT_VALUE_CHANGED 事件
*/
lv_obj_t * lv_checkbox_create(lv_obj_t * parent);
/**
* 创建下拉列表控件(用于隐藏选项列表,点击展开选择,支持自定义选项内容)
* @param parent 父对象指针(lv_obj_t*,不可为NULL)
* @return 新创建的下拉列表对象指针(lv_obj_t*),创建失败返回NULL
* @note 需通过 lv_dropdown_set_options(dropdown, "选项1\n选项2\n选项3") 设置下拉选项(选项间用 '\n' 分隔);
* 当前选中项索引通过 lv_dropdown_get_selected(dropdown) 获取(int32_t,从 0 开始);
* 展开/收起、选中变化时触发 LV_EVENT_VALUE_CHANGED 事件
*/
lv_obj_t * lv_dropdown_create(lv_obj_t * parent);
/**
* 创建表格控件(用于展示行列数据,支持单元格文本设置、合并单元格、样式自定义)
* @param parent 父对象指针(lv_obj_t*,不可为NULL)
* @return 新创建的表格对象指针(lv_obj_t*),创建失败返回NULL
* @note 需先通过 lv_table_set_row_cnt(table, row_num)、lv_table_set_col_cnt(table, col_num) 设置行列数;
* 单元格文本通过 lv_table_set_cell_value(table, row, col, "内容") 设置;
* 支持合并单元格(lv_table_merge_cells(table, row, col, merge_row, merge_col)),合并后仅左上角单元格文本生效
*/
lv_obj_t * lv_table_create(lv_obj_t * parent);
大小与位置设置
/**
* 单独设置对象的宽度
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @param w 宽度值(int32_t)coord:坐标,支持两种类型:像素值(如300);
* 父对象宽度百分比(如LV_PCT(50)表示父对象宽度的50%)
* @return 无返回值(void)
* @note 仅修改宽度,高度保持不变;
* 会覆盖通过lv_obj_set_size()设置的宽度值;
* 若使用百分比,实际宽度会随父对象宽度变化自动更新
*/
void lv_obj_set_width(lv_obj_t * obj, int32_t w);
/**
* 单独设置对象的高度
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @param h 高度值(int32_t),支持三种类型:像素值;
* 父对象高度百分比(LV_PCT(n));
* 自适应内容高度(LV_SIZE_CONTENT)
* @return 无返回值(void)
* @note 仅修改高度,宽度保持不变;
* 会覆盖通过lv_obj_set_size()设置的高度值;
* 设为LV_SIZE_CONTENT时,高度会自动适配对象内部内容(如子对象、文本)的实际高度
*/
void lv_obj_set_height(lv_obj_t * obj, int32_t h);
/**
* 同时设置对象的宽度和高度
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @param w 宽度值(int32_t),支持像素值或父对象宽度百分比(LV_PCT(n))
* @param h 高度值(int32_t),支持像素值、父对象高度百分比(LV_PCT(n))或自适应内容(LV_SIZE_CONTENT)
* @return 无返回值(void)
* @note 会同时覆盖对象之前的宽度和高度设置;
* 宽高单位可混合使用(如宽度用百分比,高度用像素)
*/
void lv_obj_set_size(lv_obj_t * obj, int32_t w, int32_t h);
/**
* 获取对象的实际宽度(像素值)
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @return 实际宽度(int32_t),单位为像素
* @note 无论设置时使用像素、百分比还是其他单位,均返回最终渲染的实际像素宽度;
* 若对象未完成渲染,可能返回初始默认值(如0)
*/
int32_t lv_obj_get_width(lv_obj_t * obj);
/**
* 获取对象的实际高度(像素值)
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @return 实际高度(int32_t),单位为像素
* @note 无论设置时使用何种单位,均返回最终渲染的实际像素高度;
* 若设置为LV_SIZE_CONTENT,返回值会随内部内容变化而更新
*/
int32_t lv_obj_get_height(lv_obj_t * obj);
/**
* 单独设置对象的X轴坐标(相对于父对象)
* @param obj 目标对象指针(lv_obj_t*)
* @param x X轴坐标(int32_t),以父对象左上角为原点,正数向右、负数向左
* @return 无返回值(void)
* @note 仅修改X坐标,Y坐标保持不变;
* 会覆盖通过lv_obj_set_pos()设置的X坐标值
*/
void lv_obj_set_x(lv_obj_t * obj, int32_t x);
/**
* 单独设置对象的Y轴坐标(相对于父对象)
* @param obj 目标对象指针(lv_obj_t*)
* @param y Y轴坐标(int32_t),以父对象左上角为原点,正数向下、负数向上
* @return 无返回值(void)
* @note 仅修改Y坐标,X坐标保持不变;
* 会覆盖通过lv_obj_set_pos()设置的Y坐标值
*/
void lv_obj_set_y(lv_obj_t * obj, int32_t y);
/**
* 同时设置对象的X、Y轴坐标(相对于父对象)
* @param obj 目标对象指针(lv_obj_t*)
* @param x X轴坐标(int32_t),正数向右、负数向左
* @param y Y轴坐标(int32_t),正数向下、负数向上
* @return 无返回值(void)
* @note 会同时覆盖对象之前的X、Y坐标设置;
* 坐标原点为父对象左上角,单位为像素
*/
void lv_obj_set_pos(lv_obj_t * obj, int32_t x, int32_t y);
/**
* 获取对象的实际X轴坐标(相对于父对象)
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @return 实际X坐标(int32_t),单位为像素
* @note 返回值为相对于父对象左上角的最终坐标,受布局调整(如对齐、居中)影响;
* 与lv_obj_set_x()设置值一致(无自动布局时)
*/
int32_t lv_obj_get_x(lv_obj_t * obj);
/**
* 获取对象的实际Y轴坐标(相对于父对象)
* @param obj 目标对象指针(lv_obj_t*,不可为NULL)
* @return 实际Y坐标(int32_t),单位为像素
* @note 返回值为相对于父对象左上角的最终坐标,受布局调整影响;
* 与lv_obj_set_y()设置值一致(无自动布局时)
*/
int32_t lv_obj_get_y(lv_obj_t * obj);
对齐方式设置
/**
* 相对于父对象进行对齐(快速定位对象在父容器中的位置)
* @param obj 目标对象指针(lv_obj_t*,不可为NULL),需对齐的对象
* @param align 对齐方式(lv_align_t),指定对象相对于父对象的对齐基准点
* 常见取值:LV_ALIGN_CENTER(父对象中心)、LV_ALIGN_TOP_LEFT(父对象左上角)、
* LV_ALIGN_BOTTOM_RIGHT(父对象右下角)、LV_ALIGN_LEFT_MID(父对象左侧中间)等
* @param x_offset X轴偏移量(int32_t),基于对齐基准点的水平偏移(正数向右,负数向左)
* @param y_offset Y轴偏移量(int32_t),基于对齐基准点的垂直偏移(正数向下,负数向上)
* @return 无返回值(void)
* @note 对齐基准为目标对象的父对象,若对象无父对象(顶层对象),则相对于屏幕对齐;
* 会覆盖对象之前通过 lv_obj_set_pos()/lv_obj_set_x()/lv_obj_set_y() 设置的位置;
* 父对象大小变化时,若开启布局自动更新,对象会重新保持对齐状态
*/
void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_offset, int32_t y_offset);
/**
* 将目标对象相对于基准对象进行对齐
* @param obj 要对齐的目标对象指针(lv_obj_t*,必须指向有效对象,不可为NULL)
* @param base 基准对象指针(const lv_obj_t*,可为NULL;若为NULL,默认以目标对象的父对象为基准)
* @param align 对齐方式(lv_align_t),指定目标对象与基准对象的对齐点(如LV_ALIGN_TOP_LEFT表示目标对象左上角与基准对象左上角对齐,LV_ALIGN_CENTER表示中心点对齐等)
* @param x_ofs X轴偏移量(int32_t),单位为像素;在对齐基础上,目标对象沿X轴偏移的距离(正值向右,负值向左)
* @param y_ofs Y轴偏移量(int32_t),单位为像素;在对齐基础上,目标对象沿Y轴偏移的距离(正值向下,负值向上)
* @note 对齐逻辑:根据`align`参数定义的对齐点,先将目标对象的指定点与基准对象的对应点重合,再应用`x_ofs`和`y_ofs`偏移;
* `lv_align_t`枚举包含多种预定义对齐方式(如边缘对齐、角对齐、中心对齐等),可覆盖大部分常见布局场景;
* 若基准对象`base`被移动或尺寸改变,目标对象不会自动重新对齐,需手动再次调用该函数更新位置
*/
void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, int32_t x_ofs, int32_t y_ofs);
圆角设置
/**
* 设置对象指定部分的圆角样式(控制对象边角的圆润程度)
* @param obj 目标对象指针(lv_obj_t*,不可为NULL),需设置圆角的对象(如按钮、容器等)
* @param value 圆角半径(int32_t),单位为像素;特殊值LV_RADIUS_CIRCLE表示完全圆形(需对象宽高相等时生效)
* @param selector 样式选择器(lv_style_selector_t),用于指定应用该样式的对象部分(part)和状态(state)
* 通常通过LV_PART_XXX(如LV_PART_MAIN,主体部分)和LV_STATE_XXX(如默认状态0)组合而成
* @return 无返回值(void)
* @note 圆角半径越大,对象边角越圆润;半径为0时边角为直角;
* 若对象宽高不相等,使用LV_RADIUS_CIRCLE会生成椭圆形边角,而非正圆形;
* 同一对象的不同部分(如主体、边框)和不同状态(如默认、选中)可设置不同圆角样式;
* 会覆盖之前对同一选择器(相同part和state)设置的圆角样式
*/
void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
LVGL盒子模型
LVGL 遵循 CSS 的 border-box 模型。
盒子模型组成
LVGL 盒子模型的 5 个组成部分:

| 组成部分 | 定义 | 核心调整接口 |
|---|---|---|
| Bounding(边界) | 对象的 “外框”,即lv_obj_set_size设置的宽高范围,包含 Border、Padding、Content,是对象的整体尺寸。 |
lv_obj_set_size():设置边界宽高;lv_obj_get_width():获取边界宽度。 |
| Border(边框) | 边界内侧的线条,占 Bounding 空间,可设置宽度、颜色、样式(实线 / 虚线),用于美化对象边框。 | lv_obj_set_style_border_width():边框宽度;lv_obj_set_style_border_color():边框颜色。 |
| Padding(内边距) | 边框内侧与 Content 的间距,控制子对象与父对象边框的距离(子对象不会超出 Padding 范围)。 | lv_obj_set_style_pad_top():上内边距;lv_obj_set_style_pad_left():左内边距;lv_obj_set_style_pad_all():所有内边距统一设置。 |
| Content(内容区) | 实际显示内容的区域(如标签的文本、图像的像素),尺寸 = Bounding 宽高 - 2×Border 宽度 - 2×Padding。 | 由内容自动决定(如标签文本长度、图像尺寸),无需手动设置。 |
| Outline(轮廓) | 边框外侧的线条,不占空间,仅用于视觉突出(如输入框聚焦时的高亮框),不会影响对象布局。 | lv_obj_set_style_outline_width():轮廓宽度;lv_obj_set_style_outline_color():轮廓颜色。 |
自定义代码
创建mycode/目录、配置CMakeLists.txt、测试运行,补充完整的自定义代码结构及编译配置:
目录结构
项目根目录/
├── bin/ # 编译输出目录(可执行文件)
├── build/ # 编译中间文件目录
├── cmake/ # CMake辅助配置
├── lvgl/ # LVGL源码目录
├── mycode/ # 自定义代码目录(《基础.docx》新增)
│ ├── obj.c # 基础对象测试代码
│ └── head.h # 自定义头文件(声明函数)
├── CMakeLists.txt # 顶层CMake配置文件
├── main.c # 主函数(调用自定义测试代码)
└── lv_conf.h # LVGL配置文件
自定义头文件mycode/head.h
#ifndef MYCODE_HEAD_H
#define MYCODE_HEAD_H
#include "lvgl/lvgl.h"
// 声明自定义测试函数
void obj_test(void); // 基础对象测试
#endif // MYCODE_HEAD_H
自定义代码mycode/test.c
#include "head.h"
/**
* 基础对象测试函数
*/
void obj_test(void) {
// 获取当前活跃屏幕(父对象)
lv_obj_t *scr = lv_scr_act();
// 在屏幕中创建基础对象(子对象)
lv_obj_t *obj = lv_obj_create(scr);
// 设置基础对象属性(大小、位置、对齐、样式)
lv_obj_set_size(obj, 180, 120); // 大小:180×120像素
lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); // 居中显示
lv_obj_set_style_bg_color(obj, lv_color_hex(0xF0F8FF), LV_PART_MAIN); // 背景色:爱丽丝蓝
lv_obj_set_style_radius(obj, 8, LV_PART_MAIN); // 圆角:8像素
lv_obj_set_style_border_width(obj, 2, LV_PART_MAIN); // 边框:2像素
lv_obj_set_style_border_color(obj, lv_color_hex(0x87CEEB), LV_PART_MAIN); // 边框色:天蓝色
// 在基础对象上创建子标签(显示文本)
lv_obj_t *label = lv_label_create(obj);
lv_label_set_text(label, "hello");
lv_obj_set_style_text_font(label, &lv_font_montserrat_18, LV_PART_MAIN); // 字体:18号
lv_obj_center(label); // 标签在基础对象内居中
}
配置CMakeLists.txt
补充完整的顶层CMakeLists.txt,确保mycode/目录下的代码被编译:
# 顶层 CMakeLists.txt
...
...
# 新增如下两行
include_directories(${PROJECT_SOURCE_DIR}/mycode)
file(GLOB_RECURSE MY_SOURCES ${PROJECT_SOURCE_DIR}/mycode/*.c)
# 新增main所依赖的文件¥{MY_SOURCES}
add_executable(main main.c mouse_cursor_icon.c ${MY_SOURCES})
...
...
主函数main.c(调用自定义测试代码)
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lvgl/examples/lv_examples.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "mycode/head.h"
static const char *getenv_default(const char *name, const char *dflt)
{
return getenv(name) ? : dflt;
}
#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{
const char *device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");
lv_display_t * disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, device);
}
#elif LV_USE_LINUX_DRM
static void lv_linux_disp_init(void)
{
const char *device = getenv_default("LV_LINUX_DRM_CARD", "/dev/dri/card0");
lv_display_t * disp = lv_linux_drm_create();
lv_linux_drm_set_file(disp, device, -1);
}
#elif LV_USE_SDL
static void lv_linux_disp_init(void)
{
const int width = atoi(getenv("LV_SDL_VIDEO_WIDTH") ? : "800");
const int height = atoi(getenv("LV_SDL_VIDEO_HEIGHT") ? : "480");
lv_sdl_window_create(width, height);
}
#else
#error Unsupported configuration
#endif
void lv_touchpad_init(void)
{
// 创建触摸屏设备,并关联到屏幕
lv_indev_t *touchpad = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
lv_indev_set_disp(touchpad, lv_disp_get_default());
}
int main(void)
{
lv_init();
/*Linux display device init*/
lv_linux_disp_init();
lv_touchpad_init();
/*Create a Demo*/
obj_test();
/*Handle LVGL tasks*/
while(1) {
lv_timer_handler();
usleep(5000);
}
return 0;
}

浙公网安备 33010602011771号