本文主要是系统的理论知识,开始一遍了解功能即可,后续用到再当字典查,文中涉及的实操界面,需要先搭建环境,需观看我上一篇文章:创建第一个LVGL工程https://mp.weixin.qq.com/s/zJ8hf4f36GGpJW_8vHf0Jw
想象一下,你要用积木搭建一个城堡。在LVGL中:
核心思想:LVGL中一切皆对象,所有你能看到的东西(按钮、文字、图片)都是对象!
// 获取当前屏幕(就像拿到一张画布)lv_obj_t *screen = lv_scr_act();// 创建一个基础对象(就像在画布上放一个透明盒子)lv_obj_t *my_object = lv_obj_create(screen);代码解释:
lv_scr_act():获取当前活动的屏幕(画布)lv_obj_create():创建对象的函数parent参数:指定这个对象放在哪个"父对象"上// 方式1:分两步lv_obj_t *screen = lv_scr_act();lv_obj_t *obj = lv_obj_create(screen);// 方式2:一步到位(更简洁)lv_obj_t *obj = lv_obj_create(lv_scr_act());// 方式3:创建子对象(对象里面再放对象)lv_obj_t *parent = lv_obj_create(lv_scr_act());lv_obj_t *child = lv_obj_create(parent); // 这个对象放在parent里面set_size()// 设置宽度和高度lv_obj_set_size(obj, 100, 50); // 宽100像素,高50像素// 也可以分开设置lv_obj_set_width(obj, 100); // 设置宽度lv_obj_set_height(obj, 50); // 设置高度// 使用百分比(相对于父对象)lv_obj_set_size(obj, LV_PCT(50), LV_PCT(30)); // 宽占父对象50%,高占30%set_pos()// 设置x和y坐标(相对于父对象的左上角)lv_obj_set_pos(obj, 100, 200); // x=100像素,y=200像素// 也可以分开设置lv_obj_set_x(obj, 100); // 设置x坐标lv_obj_set_y(obj, 200); // 设置y坐标void create_black_square() { // 创建对象 lv_obj_t *square = lv_obj_create(lv_scr_act()); // 设置大小 lv_obj_set_size(square, 100, 100); // 设置位置(距离左上角50, 50) lv_obj_set_pos(square, 50, 50); // 设置背景颜色为黑色 lv_obj_set_style_bg_color(square, lv_color_hex(0x000000), LV_PART_MAIN);}
// 先创建的在下面,后创建的压在上面lv_obj_t *obj1 = lv_obj_create(lv_scr_act()); // 在下面lv_obj_t *obj2 = lv_obj_create(lv_scr_act()); // 在上面lv_obj_set_pos(obj2, 50, 50); // 偏移位置 // 设置不同颜色以便区分lv_obj_set_style_bg_color(obj1, lv_color_hex(0x000000), LV_PART_MAIN); // 黑色lv_obj_set_style_bg_color(obj2, lv_color_hex(0xFF0000), LV_PART_MAIN); // 红色运行结果:你会看到红色的方块盖在黑色方块上面。

// 获取父对象(谁"装着"我)lv_obj_t *parent = lv_obj_get_parent(obj);// 获取子对象(我"装着"谁)// idx=0:第一个子对象,idx=1:第二个子对象,idx=-1:最后一个子对象lv_obj_t *first_child = lv_obj_get_child(parent, 0);lv_obj_t *last_child = lv_obj_get_child(parent, -1);// 获取兄弟对象(和我同一个父亲的其他对象)lv_obj_t *next_brother = lv_obj_get_child(parent, idx+1);LVGL提供了18种对齐方式,最常用的有:
// 基本对齐(在父对象内对齐)LV_ALIGN_TOP_LEFT // 左上角LV_ALIGN_TOP_MID // 顶部中间LV_ALIGN_TOP_RIGHT // 右上角LV_ALIGN_CENTER // 正中间LV_ALIGN_BOTTOM_LEFT // 左下角LV_ALIGN_BOTTOM_MID // 底部中间LV_ALIGN_BOTTOM_RIGHT // 右下角LV_ALIGN_LEFT_MID // 左边中间LV_ALIGN_RIGHT_MID // 右边中间// 外部对齐(在父对象外对齐)LV_ALIGN_OUT_TOP_MID // 上方中间LV_ALIGN_OUT_BOTTOM_MID // 下方中间
// 方法1:简单对齐(在父对象内居中对齐)lv_obj_center(obj);// 方法2:指定对齐方式和偏移量lv_obj_align(obj, LV_ALIGN_TOP_LEFT, 10, 10); // 左上角,向右偏移10,向下偏移10// 方法3:相对于另一个对象对齐lv_obj_align_to(obj2, obj1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); // 在obj1下方10像素处void create_button_layout() { // 创建父容器 lv_obj_t *container = lv_obj_create(lv_scr_act()); lv_obj_set_size(container, 300, 200); lv_obj_center(container); // 创建两个按钮 lv_obj_t *btn1 = lv_btn_create(container); lv_obj_t *btn2 = lv_btn_create(container); lv_obj_set_size(btn1, 80, 40); lv_obj_set_size(btn2, 80, 40); lv_obj_align(btn1, LV_ALIGN_TOP_MID, 0, 20); // 顶部,向下20 lv_obj_align_to(btn2, btn1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); // btn1下方10}
从外到内:1. 边界(Outline) - 最外层,通常用于高亮2. 边框(Border) - 对象的边框3. 内边距(Padding) - 边框和内容之间的空隙4. 内容(Content) - 实际显示内容的部分
// 查看对象各个部分的大小int border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);int pad_all = lv_obj_get_style_pad_all(obj, LV_PART_MAIN);int outline_width = lv_obj_get_style_outline_width(obj, LV_PART_MAIN);// 修改盒子属性lv_obj_set_style_border_width(obj, 2, LV_PART_MAIN); // 边框宽2像素lv_obj_set_style_pad_all(obj, 10, LV_PART_MAIN); // 内边距10像素lv_obj_set_style_outline_width(obj, 5, LV_PART_MAIN); // 边界宽5像素lv_obj_set_style_radius(obj, 10, LV_PART_MAIN); // 圆角10像素void create_tight_layout() { // 创建对象 lv_obj_t *obj = lv_obj_create(lv_scr_act()); lv_obj_set_size(obj, 100, 100); lv_obj_center(obj); // 去除所有间距和圆角 lv_obj_set_style_pad_all(obj, 0, LV_PART_MAIN); lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN); lv_obj_set_style_outline_width(obj, 0, LV_PART_MAIN); lv_obj_set_style_radius(obj, 0, LV_PART_MAIN); // 去掉圆角 // 现在对象之间可以完全贴合了}示例:
void create_tight_layout() { //创建对像 lv_obj_t * btn1 = lv_obj_create(lv_scr_act()); lv_obj_t * btn2 = lv_obj_create(lv_scr_act()); //设置大小 lv_obj_set_size(btn1, 80, 40); lv_obj_set_size(btn2, 80, 40); //设置位置 lv_obj_align(btn1, LV_ALIGN_TOP_MID, 0, 20); // 顶部,向下20 lv_obj_align_to(btn2, btn1, LV_ALIGN_OUT_BOTTOM_MID, 0, 0); // btn1下方10 //设置颜色 lv_obj_set_style_bg_color(btn1, lv_color_hex(0x000000), LV_PART_MAIN); lv_obj_set_style_bg_color(btn2, lv_color_hex(0x00FF00), LV_PART_MAIN); //去除所有间距和圆角 lv_obj_set_style_pad_all(btn1, 0, LV_PART_MAIN); lv_obj_set_style_border_width(btn1, 0, LV_PART_MAIN); lv_obj_set_style_outline_width(btn1, 0, LV_PART_MAIN); lv_obj_set_style_radius(btn1, 0, LV_PART_MAIN); // 去掉圆角 lv_obj_set_style_pad_all(btn2, 0, LV_PART_MAIN); lv_obj_set_style_border_width(btn2, 0, LV_PART_MAIN); lv_obj_set_style_outline_width(btn2, 0, LV_PART_MAIN); lv_obj_set_style_radius(btn2, 0, LV_PART_MAIN); // 去掉圆角}
标志用来控制对象的行为特性:
// 常用标志LV_OBJ_FLAG_CLICKABLE // 对象可以被点击LV_OBJ_FLAG_SCROLLABLE // 对象可以滚动LV_OBJ_FLAG_HIDDEN // 隐藏对象LV_OBJ_FLAG_CHECKABLE // 可以被选中/取消选中// 添加标志lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE);// 移除标志lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE);// 检查是否有某个标志bool is_clickable = lv_obj_has_flag(obj, LV_OBJ_FLAG_CLICKABLE);状态表示对象当前的情况:
// 常用状态LV_STATE_DEFAULT // 默认状态LV_STATE_PRESSED // 被按下LV_STATE_FOCUSED // 获得焦点LV_STATE_DISABLED // 禁用状态LV_STATE_CHECKED // 被选中// 可以组合多个状态LV_STATE_PRESSED | LV_STATE_FOCUSED // 按下且获得焦点// 事件回调函数,处理事件的行为static void event_handler(lv_event_t *e) { printf("对象obj被点击了!\n");}// 绑定事件到对象void setup_object_with_events() { lv_obj_t *obj = lv_obj_create(lv_scr_act()); lv_obj_set_size(obj, 100, 100); lv_obj_center(obj); lv_obj_set_style_bg_color(obj,lv_color_hex(0x000000),LV_PART_MAIN); // 使对象可点击 lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE); // 绑定点击事件 lv_obj_add_event_cb(obj, event_handler, LV_EVENT_CLICKED, NULL);}
// 输入设备事件LV_EVENT_PRESSED // 对象被按下LV_EVENT_CLICKED // 对象被点击(按下后释放)LV_EVENT_LONG_PRESSED // 长按LV_EVENT_VALUE_CHANGED // 值改变(如滑块拖动)// 绘图事件LV_EVENT_DRAW_MAIN // 主绘图阶段LV_EVENT_DRAW_POST // 后绘图阶段// 其他事件LV_EVENT_DELETE // 对象被删除LV_EVENT_SIZE_CHANGED // 大小改变// 方式1:直接设置样式(快速简单)lv_obj_set_style_bg_color(obj, lv_color_hex(0xFF0000), LV_PART_MAIN);// 方式2:创建样式对象(可以复用)static lv_style_t my_style; // 定义样式lv_style_init(&my_style); // 初始化样式lv_style_set_bg_color(&my_style, lv_color_hex(0xFF0000)); // 设置背景色lv_style_set_radius(&my_style, 10); // 设置圆角// 应用样式到对象lv_obj_add_style(obj, &my_style, LV_PART_MAIN);selector(选择器)决定了样式应用到对象的哪个部分,在什么状态下生效。
// 常用部件(Part)LV_PART_MAIN // 主体部分(所有对象都有)LV_PART_KNOB // 旋钮/手柄部分(滑块、开关等)LV_PART_INDICATOR // 指示器/进度部分(进度条、滑块等)LV_PART_SCROLLBAR // 滚动条部分(带滚动的容器)LV_PART_CURSOR // 光标部分(文本框光标)LV_PART_SELECTED // 选中部分(列表项选中状态)LV_PART_ITEMS // 项目部分(表格、列表的单元格)LV_PART_TICKS // 刻度部分(图表、仪表的刻度线)// 常用状态LV_STATE_DEFAULT // 默认状态LV_STATE_PRESSED // 被按下LV_STATE_FOCUSED // 获得焦点LV_STATE_DISABLED // 禁用状态LV_STATE_CHECKED // 被选中// 可以组合多个状态LV_STATE_PRESSED | LV_STATE_FOCUSED // 按下且获得焦点示例
// 设置按钮默认状态的背景色lv_obj_set_style_bg_color(按钮, 蓝色, LV_PART_MAIN | LV_STATE_DEFAULT);// 设置按钮按下时的背景色lv_obj_set_style_bg_color(按钮, 红色, LV_PART_MAIN | LV_STATE_PRESSED);// 设置按钮禁用时的背景色lv_obj_set_style_bg_color(按钮, 灰色, LV_PART_MAIN | LV_STATE_DISABLED);简单理解:selector就像在说"我要给这个按钮的[主要部分],在[按下状态时]设置背景色"。
// 背景相关lv_obj_set_style_bg_color(obj, color, selector); // 背景颜色lv_obj_set_style_bg_opa(obj, opa, selector); // 背景透明度(0-255)// 边框相关lv_obj_set_style_border_width(obj, width, selector); // 边框宽度lv_obj_set_style_border_color(obj, color, selector); // 边框颜色// 文字相关lv_obj_set_style_text_color(obj, color, selector); // 文字颜色lv_obj_set_style_text_font(obj, font, selector); // 文字字体// 位置相关lv_obj_set_style_pad_all(obj, value, selector); // 所有方向内边距lv_obj_set_style_pad_top(obj, value, selector); // 上内边距lv_obj(基础对象,所有控件的"祖先")├── lv_btn(按钮)├── lv_label(标签)├── lv_slider(滑块)├── lv_switch(开关)├── lv_img(图片)├── lv_bar(进度条)└── ...(其他所有控件)void test_inheritance() { // 创建一个基础对象 lv_obj_t *obj = lv_obj_create(lv_scr_act()); // 创建一个按钮(按钮继承自基础对象) lv_obj_t *btn = lv_btn_create(lv_scr_act()); // 它们都可以使用相同的函数设置属性 lv_obj_set_size(obj, 100, 50); lv_obj_set_size(btn, 100, 50); // 按钮也有size属性! lv_obj_set_pos(obj, 50, 50); lv_obj_set_pos(btn, 50, 150); // 按钮也有pos属性! lv_obj_set_style_bg_color(obj, lv_color_hex(0x000000), LV_PART_MAIN); lv_obj_set_style_bg_color(btn, lv_color_hex(0xFF0000), LV_PART_MAIN); // 按钮也有背景色!}要点:因为按钮继承自基础对象,所以按钮拥有基础对象的所有功能!
创建一个包含以下元素的控制面板:
#include "lvgl.h"// 事件处理函数static void square_clicked(lv_event_t *e) { lv_obj_t *obj = lv_event_get_target(e); // 随机改变颜色 uint8_t r = rand() % 256; uint8_t g = rand() % 256; uint8_t b = rand() % 256; lv_color_t new_color = lv_color_make(r, g, b); lv_obj_set_style_bg_color(obj, new_color, LV_PART_MAIN);}void create_control_panel() { // 创建黑色背景容器 lv_obj_t *container = lv_obj_create(lv_scr_act()); lv_obj_set_size(container, LV_PCT(80), LV_PCT(80)); lv_obj_center(container); // 设置容器样式 lv_obj_set_style_bg_color(container, lv_color_hex(0x000000), LV_PART_MAIN); lv_obj_set_style_pad_all(container, 20, LV_PART_MAIN); lv_obj_set_style_radius(container, 10, LV_PART_MAIN); // 创建三个方块 lv_obj_t *square1 = lv_obj_create(container); lv_obj_t *square2 = lv_obj_create(container); lv_obj_t *square3 = lv_obj_create(container); // 设置方块大小 lv_obj_set_size(square1, 80, 80); lv_obj_set_size(square2, 80, 80); lv_obj_set_size(square3, 80, 80); // 设置初始颜色 lv_obj_set_style_bg_color(square1, lv_color_hex(0xFF0000), LV_PART_MAIN); lv_obj_set_style_bg_color(square2, lv_color_hex(0x00FF00), LV_PART_MAIN); lv_obj_set_style_bg_color(square3, lv_color_hex(0x0000FF), LV_PART_MAIN); // 去除方块的内边距、边框、圆角 lv_obj_set_style_pad_all(square1, 0, LV_PART_MAIN); lv_obj_set_style_border_width(square1, 0, LV_PART_MAIN); lv_obj_set_style_radius(square1, 0, LV_PART_MAIN); lv_obj_set_style_pad_all(square2, 0, LV_PART_MAIN); lv_obj_set_style_border_width(square2, 0, LV_PART_MAIN); lv_obj_set_style_radius(square2, 0, LV_PART_MAIN); lv_obj_set_style_pad_all(square3, 0, LV_PART_MAIN); lv_obj_set_style_border_width(square3, 0, LV_PART_MAIN); lv_obj_set_style_radius(square3, 0, LV_PART_MAIN); // 使方块可点击 lv_obj_add_flag(square1, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_flag(square2, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_flag(square3, LV_OBJ_FLAG_CLICKABLE); // 绑定点击事件 lv_obj_add_event_cb(square1, square_clicked, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(square2, square_clicked, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(square3, square_clicked, LV_EVENT_CLICKED, NULL); // 水平排列方块 lv_obj_align(square1, LV_ALIGN_TOP_MID, -90, 20); lv_obj_align(square2, LV_ALIGN_TOP_MID, 0, 20); lv_obj_align(square3, LV_ALIGN_TOP_MID, 90, 20);}
通过本章学习,你已经掌握了:
lv_obj_create()set_size()、set_pos()lv_obj_align()的18种对齐记住:基础对象是LVGL的基石,掌握好它,学习其他控件会事半功倍!
// 创建和基本设置lv_obj_t *obj = lv_obj_create(parent);lv_obj_set_size(obj, width, height);lv_obj_set_pos(obj, x, y);lv_obj_center(obj);// 样式设置lv_obj_set_style_bg_color(obj, color, LV_PART_MAIN);lv_obj_set_style_radius(obj, radius, LV_PART_MAIN);// 事件处理lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE);lv_obj_add_event_cb(obj, handler, LV_EVENT_CLICKED, NULL);往期推荐: