一、组件属性,样式设计

1.设置左上角坐标位置

lv_obj_set_pos(组件指针,x坐标,y坐标);

2.设置尺寸大小

lv_obj_set_size(组件, 100, 50);

3.设置对齐——LVGL原点在第四象限

lv_obj_set_align(组件地址, LV_ALIGN_CENTER);——》两个参数

lv_obj_align(组件, LV_ALIGN_CENTER,-100,0); ——》四个参数

//居中表示把整个屏幕的中心位置作为(0,0),左边x是负数,右边x是正数,上面y是负数,下面y是正数

在对齐的基础之上再进行移动

LV_ALIGN_RIGHT_MID //靠右居中

LV_ALIGN_LEFT_MID

LV_ALIGN_TOP_MID

lv_obj_align_to(组件1,组件2, LV_ALIGN_OUT_BOTTOM_MID,0,20);——》五个参数

//设置参考物对齐方式,设置组件1参考组件2,在组件2的下方居中的位置,(0,20)表示y方向往下偏移20个像素,x方向居中

4.设置背景颜色,必须设置背景透明度,否则没用

lv_obj_set_style_bg_color(label, lv_color_hex(0xff0000), LV_STATE_DEFAULT);

LV_STATE_DEFAULT = 0,代表控件默认正常状态(无按下、无聚焦、无选中、无禁用的普通释放状态)

lv_obj_set_style_bg_opa(label, 100, LV_STATE_DEFAULT); //透明度0--255,值越大,上面的红色背景越深

//透明度设置为0表示这个组件跟主界面背景一样,肉眼看跟主界面融为一体

5.设置字体大小

lv_obj_set_style_text_font(label, &lv_font_montserrat_30, LV_STATE_DEFAULT);

参数: &lv_font_montserrat_30表示字体大小

注意: lv_conf.h头文件的348行定义所有的字体大小,默认值都是0表示关闭,你需要改成1才能使用

两个设置字体的接口对比

项目

lv_obj_set_style_text_font(obj, font, sel)

lv_style_set_text_font(style, font)

操作对象

直接操作控件 obj

操作独立样式结构体lv_style_t

复用性

仅当前控件生效,无法复用

可挂载到任意多控件,全局复用

代码量

一行搞定,无需提前初始化样式

需先lv_style_init,再 add_style 挂载

适用场景

单个控件特殊字体、少量控件

大量控件统一文字样式(列表、菜单)

6.设置边框宽度

lv_obj_set_style_border_width(组件, 0,LV_PART_MAIN); //边框宽度设置为0表示去除边框

7.设置文本颜色(文字的颜色-->也叫做前景色)

lv_obj_set_style_text_color(label, lv_color_hex(0x5084db), LV_STATE_DEFAULT);

8.设置组件的标志

lv_obj_add_flag(组件, LV_OBJ_FLAG_HIDDEN); //隐藏对象

lv_obj_clear_flag(组件, LV_OBJ_FLAG_HIDDEN);//取消隐藏

9.设置组件的状态

lv_obj_add_state(按钮组件, LV_STATE_FOCUS_KEY); //按钮点击之后,按钮的背景颜色变成蓝色

lv_obj_add_state(开关组件/复选框, LV_STATE_CHECKED | LV_STATE_DISABLED); //设置开关/复选框组件不能点击

lv_obj_clear_state(开关组件/复选框, LV_STATE_CHECKED | LV_STATE_DISABLED); //取消开关/复选框组件不能点击

lv_obj_clear_state(开关组件,LV_STATE_CHECKED); //把开关组件的状态弄成关闭

10.获取组件的状态

if(lv_obj_has_state(开关组件/复选框, LV_STATE_CHECKED)) //如果开关/复选框组件被点击打开

二、基础对象的样式

Styles 用于设置对象的外观。
  • 样式是一个 lv_style_t 变量,它可以保存边框宽度、文本颜色等属性。
  • 将样式 (变量) 分配给对象就可以改变其外观。在赋值过程中,可以指定目标部分和目标状态。
  • 一个样式可以给多个对象使用(正常样式)。
  • 样式可以级联,也就是可以将多个样式分配给一个对象。所以,我们不用将所有属性都在一个样式中指定,可以通过多个样式组合的形式指定。LVGL 会优先使用我们定义的样式,如果没有就会使用默认值。
  • 后来添加的样式具有更高的优先级。也就是说如果在两种样式中指定了同一个属性,则将使用最后添加的样式。
  • 如果对象中未指定某些属性(例如文本颜色),就会从父级继承。
  • 上面说的是 “正常” 样式,对象还有本地样式,它比 “正常” 样式具有更高的优先级。
  • 可以定义有过渡效果的样式。
  • 默认有一个样式主题,我们也可以自己定义样式主题,作为默认的样式主题使用。

1.初始化

样式存储在 lv_style_t 变量中。样式变量应该是静态、全局或动态分配的。也就是它们不能是函数中的局部变量,因为当函数结束时它们会被销毁。样式初始化示例:
static lv_style_t style_obj; lv_style_init(&style_obj);
注释说明:
  1. static lv_style_t style_obj; 定义了一个 lv_style_t 类型的结构体变量 style_obj;static 修饰:存放在静态存储区,函数结束后变量不会销毁,符合 LVGL 样式的存储要求。
  2. lv_style_init(&style_obj);此时结构体内部成员全是随机垃圾值,样式还没生效,未完成初始化。

2.设置样式属性

通用函数格式

初始化完成 lv_style_t 样式变量后,使用统一格式 API 配置外观属性:
lv_style_set_<property_name>(&style, <value>);
  • 第 1 参数:样式结构体指针
  • 第 2 参数:要设置的属性对应数值

代码示例

// 设置背景颜色,十六进制黑色 lv_style_set_bg_color(&style_obj, lv_color_hex(0x000000)); // 设置背景透明度,半透明(50%不透明度) lv_style_set_bg_opa(&style_obj, LV_OPA_50); // 其余属性均遵循 lv_style_set_xxx 命名规范 lv_style_set_...

3.添加样式到对象

核心函数

样式初始化、属性配置完成后,使用唯一接口将样式绑定到控件对象:
lv_obj_add_style(obj, &style, <selector>);
参数详解:
  1. obj:目标 UI 控件对象指针,样式要挂载到这个控件上
  2. &style:lv_style_t 样式结构体的地址指针
  3. :选择器,由部件标识 + 状态标识按位或(|)组合,用于指定该样式生效的控件部位、交互状态;参数不能传入互斥标志,否则会被判定清除标记无法合并。

代码示例

// selector传0:默认正常状态,最常用 lv_obj_add_style(obj, &style_obj, 0); // selector传LV_STATE_PRESSED:仅控件被按下时,该样式生效 lv_obj_add_style(obj, &style_obj, LV_STATE_PRESSED);

补充拓展

  1. 多状态叠加写法(同时匹配按下 + 聚焦)
lv_obj_add_style(obj, &style_press_focus, LV_STATE_PRESSED | LV_STATE_FOCUSED);
  1. 部件限定(仅修改按钮背景,不修改文字)
lv_obj_add_style(btn, &bg_style, LV_PART_MAIN | 0);
  1. 同一对象可多次调用 lv_obj_add_style 挂载多个样式,后添加样式优先级更高。

4.状态和部分

States(对象交互状态)

控件可同时叠加多种状态,作为 lv_obj_add_style 第三个参数的状态选择器:
状态宏
数值
含义
LV_STATE_DEFAULT
0x0000
默认正常释放状态,传 0 等价于此
LV_STATE_CHECKED
0x0001
勾选 / 切换选中(开关、复选框)
LV_STATE_FOCUSED
0x0002
焦点(触摸点击、键盘选中)
LV_STATE_FOCUS_KEY
0x0004
仅键盘 / 编码器焦点,触摸不算
LV_STATE_EDITED
0x0008
编码器编辑中
LV_STATE_HOVERED
0x0010
鼠标悬浮,嵌入式触摸屏一般不支持
LV_STATE_PRESSED
0x0020
手指 / 鼠标按下
LV_STATE_SCROLLED
0x0040
正在滚动
LV_STATE_DISABLED
0x0080
控件禁用,不可交互
LV_STATE_USER_1~4
0x1000/0x2000/0x4000/0x8000
4 组自定义状态,自由拓展交互样式
多状态叠加写法:LV_STATE_PRESSED | LV_STATE_FOCUSED

Part(控件内部子部件)

每个控件由多个子部件组成,可单独给某一部分设置独立样式,同样作为 lv_obj_add_style 选择器参数,和状态按位或组合使用:
部件宏
作用说明
LV_PART_MAIN
主体背景,绝大多数控件默认绘制区域
LV_PART_SCROLLBAR
滚动条部件
LV_PART_INDICATOR
指示器:滑块轨道、开关底色、复选框勾选区域
LV_PART_KNOB
可拖动旋钮 / 滑块手柄
LV_PART_SELECTED
列表 / 表格中被选中条目
LV_PART_ITEMS
批量重复元素:表格单元格、列表项
LV_PART_TICKS
刻度(仪表、进度条刻度)
LV_PART_CURSOR
光标(文本框输入光标、图表游标)
LV_PART_CUSTOM_FIRST
自定义部件起始标识,用于拓展控件

selector 组合使用示例(Part + State)

// 按钮主体,按下状态时生效该样式 lv_obj_add_style(btn, &style_press, LV_PART_MAIN | LV_STATE_PRESSED); // 滑块旋钮,禁用状态样式 lv_obj_add_style(slider, &style_dis_knob, LV_PART_KNOB | LV_STATE_DISABLED); // 默认全部主体正常状态(最常用) lv_obj_add_style(obj, &style_normal, 0);
  • selector = 部件 (Part) | 状态 (State),两者可以自由按位或合并;
  • 不传 Part(只写状态 / 0)时,默认等价 LV_PART_MAIN
  • 样式匹配规则:控件当前部件 + 当前状态同时匹配 selector,该套样式才会生效;

5.本地样式

除了“普通”样式外,对象还可以存储本地样式。
本地样式与普通样式类似,但是它不能在其他对象之间共享。如果使用本地样式,将自动分配局部样式,并在删除对象时释放。本地样式对于向对象添加本地自定义很有用。
本地样式的接口函数是这样的格式:lv_obj_set_style_local_(obj, , );
示例:
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffff), 0);
// 设置背景色lv_obj_set_style_bg_opa(obj, LV_OPA_50, 0);
// 设置背景透明度lv_style_set_...

6.本地样式VS普通共享样式

  1. 共享限制:本地样式仅归属当前控件对象,无法多个控件共用;普通lv_style_t样式可以一次定义、批量绑定给任意多个对象。
  2. 内存管理:本地样式由 LVGL 内核自动分配内存,控件lv_obj_del()销毁时自动释放,无需手动管理;普通样式需要自己保证全局 /static 生命周期,不能是函数局部栈变量。
  3. 优先级:本地样式优先级高于所有通过lv_obj_add_style()挂载的普通级联样式,相同属性会覆盖普通样式。
  4. 适用场景:仅给单个控件做一次性自定义外观,无需复用样式时使用;批量统一外观优先用普通共享样式。
对比项
本地样式
lv_obj_set_style_xxx
普通共享样式 lv_style_t + lv_obj_add_style
复用性
仅当前控件可用,不能共享
一个 style 可批量绑定给 N 个按钮 / 窗口
内存管理
对象销毁自动释放,无需手动操作
需手动lv_style_init,无需手动销毁
优先级
更高,覆盖共享样式
更低,会被本地样式覆盖
使用场景
单个控件独有的特殊外观
统一批量 UI(全部按钮同色、全部标签同字体)

三、基础对象的事件

1.事件是什么

当发生用户可能感兴趣的事情时,LVGL 中会触发事件,例如当一个对象:
  • 被点击
  • 滚动
  • 数值改变
  • 重绘
  • 等等。。

2.事件操作

添加事件回调

lv_event_dsc_t lv_obj_add_event_cb(obj, event_cb, event_code, user_data);
作用:给控件绑定事件处理函数,当触发指定event_code事件时自动执行回调
参数:
obj:目标控件对象
event_cb:事件回调函数,原型固定为 void (*lv_event_cb_t)(lv_event_t e)event_code:要监听的事件类型(如LV_EVENT_CLICKED点击、LV_EVENT_VALUE_CHANGED数值变更)
user_data:自定义用户数据,回调中可通过lv_event_get_user_data(e)
返回值:lv_event_dsc_t 事件描述符,用于精准删除事件

手动发送事件

void lv_event_send(obj, event_cb, event_code, user_data);
作用:手动主动给控件触发一次指定事件,无需用户真实操作,常用于模拟交互参数含义与lv_obj_add_event_cb一致,调用后会直接执行绑定好的回调函数。
参数:(与 lv_obj_add_event_cb 完全一致)
obj:目标 UI 控件对象(lv_obj_t*)
event_cb:要触发的事件回调函数(lv_event_cb_t)
event_code:事件类型码(如 LV_EVENT_CLICKED、LV_EVENT_VALUE_CHANGED)
user_data:自定义透传数据,回调内可通过lv_event_get_user_data(e)获取
返回值:无返回值(void 类型函数)

删除事件

void lv_obj_remove_event_cb(obj, event_cb);
作用:根据回调函数地址,删除目标控件上所有绑定了该回调的事件;如果同一个回调绑定了多种事件码,会一次性全部清除。适合模块整体销毁时批量清理。
参数:
obj:目标 UI 控件对象(lv_obj_t*)
event_cb:待删除的事件回调函数指针(lv_event_cb_t)
返回值:无返回值(void 类型函数)
lv_obj_remove_event_dsc(obj, event_dsc); //event_dsc 是 lv_obj_add_event_cb 返回的指针
作用:通过lv_obj_add_event_cb添加事件时返回的事件描述符,精准删除单一条事件绑定;不会误删同一控件下其他使用相同回调的事件,工程开发推荐优先使用。
参数:
obj:目标 UI 控件对象(lv_obj_t*)
event_dsc:添加事件时lv_obj_add_event_cb返回的事件描述符(lv_event_dsc_t*)
返回值:无返回值(void 类型函数)

3.事件类型

  • 输入设备事件 (Input device events)
  • 绘图事件 (Drawing events)
  • 其他事件 (Special events)
  • 特殊事件 (Other events)
  • 自定义事件 (Custom events)

4.事件回调函数的 lv_event_t 参数

事件回调函数只有一个参数,这个参数对我们的作为非常大,现在的版本提供这些功能:
static void my_event_cb(lv_event_t * event);
  1. 获取触发的事件代码:
lv_event_code_t code = lv_event_get_code(e);
  1. 获取触发事件的对象:
lv_obj_t * target = lv_event_get_target(e);
  1. 获取最初触发事件的对象 (事件冒泡):
lv_obj_t * target = lv_event_get_current_target(e);
  1. 获取事件传递的用户数据:
  • lv_event_get_user_data(e); 获取使用 lv_obj_add_event_cb 传递的用户数据
  • lv_event_get_param(e); 获取使用 lv_event_send 传递的用户数据

5.事件冒泡

如果对象启用了 lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE),该对象的所有事件将会发送到该对象的父级。如果父级也启用了 LV_OBJ_FLAG_EVENT_BUBBLE,那么事件继续发送到他的父级,依此类推。
  • lv_event_get_target(e); 获取触发事件的当前对象。
  • lv_event_get_current_target(e); 获取事件冒泡的父对象。 备注:两个都是lv_event_t类型结构体中的成员
lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE); // add_flag:给对象添加 / 开启该冒泡标志 lv_obj_clear_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE); // clear_flag:清除 / 关闭冒泡标志

LVGL 事件冒泡完整解读

1. 冒泡机制原理
LVGL 控件是树形层级结构(子控件嵌套在父容器内):
  1. 给控件开启 LV_OBJ_FLAG_EVENT_BUBBLE 标志后,自身产生的交互事件会向上传递给父控件;
  2. 若父控件同样开启冒泡标志,事件会继续向上传递给祖父控件,直到根屏幕;
  3. 每一层开启冒泡的父控件,绑定的事件回调都会依次执行。
2. target 与 current_target 核心区分
API
返回对象
冒泡场景举例(容器内按钮)
lv_event_get_target(e)
绑定回调的控件(监听对象)
容器绑定回调 → 返回容器
lv_event_get_current_target(e)
真正产生交互的原始控件(事件源头)
点击按钮触发冒泡 → 返回按钮
3. 冒泡开关 API 说明
开启冒泡
lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);
作用:开启当前对象的事件向上冒泡能力。
关闭冒泡
lv_obj_clear_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);
作用:关闭冒泡,当前对象产生的事件不会向上传递。
4. 典型使用场景
  • 容器统一处理:页面面板绑定点击回调,内部所有子按钮开启冒泡,点击任意子控件都能触发面板回调;
  • 分层交互逻辑:子控件做细分操作,父容器做统一的页面背景响应;
  • 全局拦截:给屏幕根对象开启冒泡,可捕获页面内所有控件的交互事件。
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐