LVGL详解
LVGL(Light and Versatile Graphics Library)是一款开源、轻量级且高度可定制的嵌入式图形库,专为资源受限的设备(如 MCU、嵌入式 Linux 系统)设计,核心目标是简化图形界面(GUI)的开发流程。
LVGL 的核心架构:分层设计
LVGL 采用分层架构,降低了硬件与软件的耦合度,方便移植和维护。从下到上分为 3 层:
层级 | 核心作用 | 开发者需做的工作 |
---|---|---|
硬件抽象层(HAL) | 连接 LVGL 与底层硬件,负责 “显示输出” 和 “输入采集”。 | 实现 2 个核心驱动: 1. 显示驱动(将 LVGL 的图像数据输出到屏幕) 2. 输入驱动(将触摸 / 按键/等外设数据传给 LVGL) |
核心层(Core) | LVGL 的核心逻辑,包括对象管理、事件处理、动画引擎、内存管理、主题管理等。 | 无需修改,直接调用 API 即可。 |
控件层(Widgets) | 基于核心层实现的预制 UI 控件(如按钮、列表),是开发者直接使用的 “组件”。 | 调用控件 API 创建界面,或自定义扩展控件。 |
LVGL 关键概念:理解核心逻辑
要熟练使用 LVGL,需先掌握 3 个核心概念:
一、对象(Object):UI 的基本单元
LVGL 中所有控件都是 “对象”(如按钮是lv_btn
对象,标签是lv_label
对象),对象具有以下特性:
- 父子关系:每个对象都有一个父对象(除了最顶层的 “屏幕对象”),子对象的位置、显示状态会受父对象影响(如父对象隐藏,子对象也隐藏)。
- 属性可配置:每个对象都有 “样式”(颜色、字体、尺寸)、“事件回调”(点击、滑动等交互响应)、“状态”(如按钮的 “按下”,“释放” 状态)。
- 示例:创建一个按钮并添加标签的代码逻辑:
// 1. 创建屏幕对象(顶层父对象) lv_obj_t *screen = lv_scr_act(); // 2. 创建按钮对象(父对象为screen) lv_obj_t *btn = lv_btn_create(screen); // 3. 设置按钮位置(距离屏幕左100px,上100px) lv_obj_set_pos(btn, 100, 100); // 4. 创建标签对象(父对象为btn,标签会随按钮移动) lv_obj_t *label = lv_label_create(btn); // 5. 设置标签文本 lv_label_set_text(label, "Click Me");
二、样式(Style):控制对象外观
样式用于定义对象的视觉属性,支持 “复用” 和 “继承”,避免重复设置:
- 基础属性:背景色、边框、圆角、阴影、字体、文本颜色、透明度等。
- 状态关联:可给对象的不同状态(如按钮的
LV_STATE_PRESSED
按下状态、LV_STATE_HOVERED
悬停状态)设置不同样式,实现交互反馈。 - 示例:给按钮设置 “默认” 和 “按下” 两种样式:
// 1. 定义按钮不同状态的样式变量(核心:用static修饰,延长生命周期) // static作用:确保样式变量不会随函数执行结束被释放,因为按钮会长期引用样式 // 两个样式分工:分别对应按钮“未点击”和“点击时”的外观 static lv_style_t style_btn_default; // 样式1:按钮默认状态(未被点击时) static lv_style_t style_btn_pressed; // 样式2:按钮按下状态(用户点击时)// 2. 初始化并配置【默认状态样式】(未点击时的外观) // lv_style_init:LVGL样式必须先初始化!作用是重置样式结构体,避免随机值导致显示异常 lv_style_init(&style_btn_default);// 2.1 设置默认状态的背景色:十六进制0x0066CC(亮蓝色,视觉清晰,适合默认按钮) // 注:LVGL v8+ 特性:样式属性设置函数(lv_style_set_xxx)不再需要状态参数 lv_style_set_bg_color(&style_btn_default, lv_color_hex(0x0066CC)); // 2.2 设置默认状态的文本色:调用lv_color_white()(直接返回白色,比lv_color_hex(0xFFFFFF)更简洁) // 作用:确保按钮上的文本与蓝色背景对比强烈,可读性高 lv_style_set_text_color(&style_btn_default, lv_color_white()); // 3. 初始化并配置【按下状态样式】(点击时的外观) // 同样先初始化样式结构体 lv_style_init(&style_btn_pressed);// 3.1 设置按下状态的背景色:十六进制0x0044AA(暗蓝色) // 设计思路: // - 仅修改“变化的属性”(背景色),文本色、内边距等未变化的属性会自动继承默认样式(LVGL样式叠加特性) // - 暗蓝色与默认的亮蓝色形成明显对比,让用户直观感知“已点击”,提升交互反馈 lv_style_set_bg_color(&style_btn_pressed, lv_color_hex(0x0044AA)); // 4. 创建按钮对象(核心组件:lv_btn是LVGL封装的“专用按钮”,自带点击状态逻辑) // 参数lv_scr_act():获取当前“活动屏幕”作为按钮的父对象,意味着按钮会显示在当前屏幕上 lv_obj_t *btn = lv_btn_create(lv_scr_act()); // 4.1 设置按钮在屏幕上的大小位置:相对于屏幕左上角(x=100px,y=100px) // 作用:避免按钮贴紧屏幕边缘,优化视觉布局 lv_obj_set_pos(btn, 100, 100); lv_obj_set_size(btn,200,100);// 5. 核心逻辑:关联“按钮状态”与“样式”(告诉LVGL“什么状态用什么样式”) // API:lv_obj_add_style(目标对象, 要应用的样式, 状态掩码) // LVGL v8+ 特性:通过第三个参数指定“样式生效的状态”,而非在样式设置时指定// 5.1 默认状态(未点击)→ 应用默认样式 // LV_STATE_DEFAULT:按钮的基础状态(无交互时),此时按钮显示亮蓝色背景+白色文本 lv_obj_add_style(btn, &style_btn_default, LV_STATE_DEFAULT); // 5.2 按下状态(点击时)→ 应用按下样式 // LV_STATE_PRESSED:用户按压按钮时的状态,此时按钮切换为暗蓝色背景(文本色继承默认样式的白色) lv_obj_add_style(btn, &style_btn_pressed, LV_STATE_PRESSED);
三、事件(Event):处理用户交互
事件是 LVGL 响应用户操作的核心机制,当用户触发动作(如点击按钮、滑动滑块)时,会触发对应的事件,开发者通过 “事件回调函数” 处理逻辑:
- 常用事件类型:
LV_EVENT_CLICKED
:对象被点击(如按钮按下后释放)。LV_EVENT_VALUE_CHANGED
:对象值改变(如滑块拖动、复选框勾选)。LV_EVENT_PRESSED
:对象被按下(未释放)。
- 示例:给按钮添加 “点击事件”,点击后修改标签文本:
// 定义事件回调函数 static void btn_click_event_cb(lv_event_t *e) {// 获取标签对象(通过事件参数传递)lv_obj_t *label = lv_event_get_user_data(e);// 修改标签文本lv_label_set_text(label, "Clicked!"); }// 给按钮绑定事件(传递标签对象作为用户数据) lv_obj_add_event_cb(btn, btn_click_event_cb, LV_EVENT_CLICKED, label);
四、LVGL 开发流程:从移植到界面实现
以 “STM32 + 触摸屏” 为例,完整开发流程分为 4 步:
-
环境搭建
- 工具:Keil MDK、STM32CubeMX(配置 GPIO、SPI/LCD 控制器、触摸芯片)。
- 导入 LVGL 库:将 LVGL 源码(从官网下载)添加到工程,配置
lv_conf.h
(开启所需功能,如控件、动画)。
-
移植底层驱动(关键步骤)
- 实现显示驱动:将 LVGL 的 “图像缓冲区” 数据通过 LCD 控制器(如 SPI、FSMC)输出到屏幕,核心是
lv_display_flush_cb
回调函数(负责将指定区域的像素数据刷新到屏幕)。 - 实现输入驱动:读取触摸芯片的坐标数据,通过
lv_indev_set_read_cb
回调函数将坐标传给 LVGL,支持 “触摸”“按键” 等输入类型。
- 实现显示驱动:将 LVGL 的 “图像缓冲区” 数据通过 LCD 控制器(如 SPI、FSMC)输出到屏幕,核心是
-
创建 UI 界面
- 基于 LVGL 控件 API 创建界面,如按钮、列表、图表等。
- 配置样式(颜色、字体)和事件(点击、滑动响应),实现交互逻辑。
-
调试与优化
- 用 LVGL Simulator 在 PC 端先调试界面布局和动画,再移植到硬件。
- 优化性能:若界面卡顿,可增加图像缓冲区大小、关闭不必要的视觉效果(如阴影)、调整刷新频率。
五、LVGL 的优势与局限性
优势 | 局限性 |
---|---|
1. 轻量级,适配低资源嵌入式设备 | 1. 高级视觉效果(如复杂动画)会占用更多 CPU 资源,可能导致卡顿 |
2. 跨平台,移植成本低 | 2. 不支持 3D 界面,仅专注于 2D GUI |
3. 控件丰富,开发效率高 | 3. 对大尺寸屏幕(如 10 英寸以上)的适配需优化缓冲区,否则内存占用较高 |
4. 开源免费,社区活跃(文档、示例丰富) | 4. 需手动移植底层驱动,对新手有一定门槛 |
LVGL基础对象(object)
在 LVGL 中,基础对象(lv_obj_t) 是所有 UI 组件(如按钮、标签、滑块等)的 “父类”,是整个 UI 系统的基石。所有组件都继承自基础对象,因此它包含了 UI 元素的公共属性(如位置、大小、样式)和通用行为(如事件响应、状态管理)。理解基础对象是掌握 LVGL 的核心。
一、基础对象的核心特性
-
层级结构基础对象通过 “父子关系” 形成层级结构:
- 每个对象有且仅有一个父对象(根对象是屏幕
lv_scr_act()
)。 - 子对象的坐标相对于父对象的左上角(0,0)。
- 父对象会裁剪超出自身边界的子对象(可通过
lv_obj_set_clip_self()
关闭裁剪)。
例:创建父子关系
lv_obj_t * parent = lv_obj_create(lv_scr_act()); // 父对象(屏幕为根) lv_obj_t * child = lv_obj_create(parent); // 子对象(父对象为parent)
- 每个对象有且仅有一个父对象(根对象是屏幕
-
样式系统基础对象的外观(颜色、边框、圆角等)由样式(lv_style_t) 定义,支持动态切换。
注意:样式需加static
LVGL 中样式加static
的核心目的是:保证样式的生命周期与引用它的 UI 对象一致,避免因样式被提前释放导致的内存访问错误。这是嵌入式 GUI 开发中针对 “局部变量生命周期不足” 的经典解决方案。- 样式通过
lv_obj_add_style()
应用到对象。 - 同一对象可同时应用多个样式(按优先级叠加)。
- 支持按 “状态” 应用不同样式(如默认、按下、聚焦状态)。
例:设置基础对象样式
// 1. 定义样式变量并声明为static // static修饰确保样式生命周期与程序一致(避免函数结束后被释放) // lv_style_t是LVGL中存储样式属性的结构体(如颜色、尺寸、边框等) static lv_style_t style;// 2. 初始化样式结构体 // 必须先调用lv_style_init初始化,否则样式属性可能存在随机值(导致显示异常) // 作用:为style分配默认内存布局,重置所有样式属性为初始状态 lv_style_init(&style);// 3. 设置样式的背景色 // 函数:lv_style_set_bg_color(样式指针, 颜色值) // 参数说明: // &style:要配置的样式变量地址 // lv_color_hex(0x007bff):通过十六进制值创建颜色(0x007bff对应蓝色) // 注意:LVGL v8+移除了状态参数(如LV_STATE_DEFAULT),样式默认应用于所有状态 lv_style_set_bg_color(&style, lv_color_hex(0x007bff)); // 背景色设置为蓝色// 4. 设置样式的圆角半径 // 函数:lv_style_set_radius(样式指针, 半径值) // 参数说明: // 20:圆角半径为20像素(值越大,圆角越明显,最大建议不超过对象短边的1/2) lv_style_set_radius(&style, 20); // 圆角半径设置为20像素// 5. 设置样式的边框宽度 // 函数:lv_style_set_border_width(样式指针, 宽度值) // 参数说明: // 2:边框宽度为2像素(0表示无边框) lv_style_set_border_width(&style, 2); // 边框宽度设置为2像素// 6. 设置样式的边框颜色 // 函数:lv_style_set_border_color(样式指针, 颜色值) // 参数说明: // lv_color_hex(0xcccccc):十六进制值0xcccccc对应浅灰色 lv_style_set_border_color(&style, lv_color_hex(0xcccccc)); // 边框颜色设置为浅灰色// 7. 创建基础UI对象(所有组件的父类) // 函数:lv_obj_create(父对象指针) // 参数说明: // lv_scr_act():返回当前活动屏幕对象(作为父对象,所有UI元素需依附于屏幕或其他父对象) // 返回值:新创建的对象指针(后续通过该指针操作对象) lv_obj_t * obj = lv_obj_create(lv_scr_act());// 8. 为对象应用样式 // 函数:lv_obj_add_style(对象指针, 样式指针, 优先级) // 参数说明: // obj:要应用样式的对象 // &style:要应用的样式 // 0:样式优先级(多个样式叠加时,优先级高的覆盖低的,通常填0即可) // 注意:LVGL v8+中不再通过状态参数区分样式,而是通过对象状态动态切换样式 lv_obj_add_style(obj, &style, 0); // 为对象应用上述样式// 9. 设置对象的尺寸 // 函数:lv_obj_set_size(对象指针, 宽度, 高度) // 参数说明: // 200:对象宽度为200像素 // 100:对象高度为100像素 lv_obj_set_size(obj, 200, 100);// 10. 设置对象在父对象中居中显示 // 函数:lv_obj_center(对象指针) // 作用:等价于lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0),即相对于父对象(屏幕)居中对齐,x/y偏移量为0 lv_obj_center(obj);
- 样式通过
-
状态管理基础对象有多种 “状态”,用于响应交互(如触摸、聚焦),常见状态:
LV_STATE_DEFAULT
:默认状态(无交互)。LV_STATE_PRESSED
:被按下(触摸 / 点击)。LV_STATE_FOCUSED
:获得焦点(如键盘选中)。LV_STATE_DISABLED
:禁用状态(不可交互)。
可通过
lv_obj_add_state()
/lv_obj_clear_state()
手动修改状态,样式会自动根据当前状态更新。 -
事件机制基础对象支持各类事件(如点击、状态变化),通过回调函数响应:
- 常用事件:
LV_EVENT_CLICKED
(点击)、LV_EVENT_VALUE_CHANGED
(值变化)、LV_EVENT_STATE_CHANGED
(状态变化)。 - 通过
lv_obj_set_event_cb()
设置事件回调。
例:处理点击事件
// 1. 定义事件回调函数(处理对象触发的事件,如点击、按压等) // static修饰:限制函数仅在当前文件可见,避免命名冲突 // 参数lv_event_t *e:事件信息结构体(包含事件类型、目标对象等关键信息) static void obj_event_cb(lv_event_t * e) {// 2. 从事件信息中获取“事件类型”(判断触发的是哪种交互,如点击、释放等)// lv_event_get_code(e):LVGL提供的API,用于提取事件类型(返回值为lv_event_code_t枚举)lv_event_code_t code = lv_event_get_code(e);// 3. 判断事件类型是否为“点击释放事件”(LV_EVENT_CLICKED)// 点击释放事件:用户按下对象后松开时触发(最常用的“点击”交互)if(code == LV_EVENT_CLICKED) {// 4. 事件触发后的处理逻辑:打印日志(需在lv_conf.h中开启LV_USE_LOG宏)// LV_LOG_USER:LVGL的日志宏,输出用户级信息(可在控制台/调试工具中查看)// 实际项目中可替换为业务逻辑(如切换页面、修改UI状态、控制硬件等)LV_LOG_USER("Object clicked!"); // 打印“对象被点击”的日志} }// 5. 创建一个基础UI对象(所有LVGL组件的父类,可理解为一个矩形容器) // lv_obj_create(parent):创建对象的API,参数为父对象(决定对象的显示层级和位置参考) // lv_scr_act():返回当前活动屏幕对象(作为父对象时,新对象直接显示在屏幕上) lv_obj_t * obj = lv_obj_create(lv_scr_act());// 6. 为对象注册事件回调(核心:关联“对象”和“事件处理函数”,让对象能响应交互) // lv_obj_add_event_cb():LVGL v8+注册事件的API(替代v7的lv_obj_set_event_cb) // 四个参数分别为:目标对象、回调函数、监听的事件类型、用户自定义数据 lv_obj_add_event_cb(obj, // 目标对象:需要响应事件的UI元素(这里是上面创建的obj)obj_event_cb, // 回调函数:事件触发时执行的函数(上面定义的obj_event_cb)LV_EVENT_CLICKED, // 监听的事件类型:仅处理“点击释放事件”(其他事件不响应)NULL // 用户数据:传递给回调函数的额外数据(无需时填NULL));
- 常用事件:
二、基础对象的核心操作 API
功能 | API 示例 | 说明 |
---|---|---|
创建对象 | lv_obj_t * obj = lv_obj_create(parent); | 父对象为parent ,若为NULL 则使用屏幕 |
设置大小 | lv_obj_set_size(obj, 200, 100); | 宽 200px,高 100px |
设置位置 | lv_obj_set_pos(obj, 50, 30); | 相对于父对象左上角(50,30) |
对齐方式 | lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); | 居中对齐,偏移量(0,0) |
设置父对象 | lv_obj_set_parent(obj, new_parent); | 更改对象的父对象 |
删除对象 | lv_obj_del(obj); | 删除对象及所有子对象 |
三、基础对象与组件的关系
所有 LVGL 组件(如lv_btn
、lv_label
、lv_slider
)都是基础对象的扩展,它们继承了基础对象的所有属性和方法,并添加了自身特有的功能:
- 例如,
lv_btn
(按钮)在基础对象上增加了 “按下反馈”“点击事件” 等特性。 - 例如,
lv_label
(标签)增加了 “文本内容”“字体设置” 等属性。
因此,对基础对象的操作(如设置大小、应用样式)完全适用于所有组件。
四、总结
基础对象(lv_obj_t
)是 LVGL 的 “万能基类”,它定义了 UI 元素的通用属性(位置、大小、样式)和行为(事件、状态)。所有组件都基于它扩展,因此掌握基础对象的操作是使用 LVGL 的前提。
核心要点:
- 父子层级决定布局和裁剪关系。
- 样式系统控制外观,支持多状态适配。
- 事件机制处理用户交互。
- 所有组件都可视为 “增强版” 基础对象。
LVGL大小设置(size)
1.
lv_obj_t * obj = lv_obj_create(lv_scr_act());//创建一个基础UI对象,并将其地址存储在obj指针中
lv_obj_set_width(obj,200);//设置宽度
lv_obj_set_height(obj,300);//设置高度
lv_obj_set_size(obj,200,300);//设置宽度和高度2.
// 创建父容器(占屏幕宽度的90%,高度的60%)
lv_obj_t *container = lv_obj_create(lv_scr_act());
lv_obj_set_width(container, lv_pct(90)); // 宽度=屏幕宽度的90%
lv_obj_set_height(container, lv_pct(60)); // 高度=屏幕高度的60%
lv_obj_center(container); // 容器在屏幕居中// 容器内的子按钮(占容器宽度的80%,高度固定50px)
lv_obj_t *btn_in_container = lv_btn_create(container);
lv_obj_set_width(btn_in_container, lv_pct(80)); // 宽度=容器的80%
lv_obj_set_height(btn_in_container, 50); // 高度固定50px
lv_obj_center(btn_in_container); // 按钮在容器内居中
百分比尺寸:lv_pct()
宏(响应式布局)
以父对象的尺寸为基准,按百分比设置子对象的宽高(实现自适应布局)
单位统一:所有尺寸 API 的单位默认是像素(px),除非使用 lv_pct()
宏(百分比)。
LVGL位置设置(position)
// 1. 创建一个基础UI对象(所有组件的父类,可理解为一个矩形容器)
// - lv_obj_create(parent):在指定父对象上创建新对象,返回对象指针
// - 参数lv_scr_act():获取当前活动屏幕(最顶层父对象),因此新对象直接显示在屏幕上
lv_obj_t * obj = lv_obj_create(lv_scr_act());// 2. 设置对象的X轴坐标(水平位置)
// - lv_obj_set_x(obj, x):单独设置对象在X轴的位置(以父对象左上角为原点)
// - 参数100:X轴坐标为100像素(距离父对象左边缘100px)
// - 此时对象位置:(X=100, Y=默认值,通常为0)
lv_obj_set_x(obj, 100);// 3. 设置对象的Y轴坐标(垂直位置)
// - lv_obj_set_y(obj, y):单独设置对象在Y轴的位置(以父对象左上角为原点)
// - 参数100:Y轴坐标为100像素(距离父对象上边缘100px)
// - 此时对象位置:(X=100, Y=100)(前两步设置的结果)
lv_obj_set_y(obj, 100);// 4. 同时设置对象的X轴和Y轴坐标(覆盖前两步的设置)
// - lv_obj_set_pos(obj, x, y):一次性设置X和Y坐标,等价于连续调用lv_obj_set_x和lv_obj_set_y
// - 参数200,200:X=200px,Y=200px(距离父对象左边缘和上边缘均为200px)
// - 最终位置:(X=200, Y=200)(此函数会覆盖之前的x、y设置)
lv_obj_set_pos(obj, 200, 200);
位置参考系:所有坐标均以父对象的左上角为原点((0,0)
),这里父对象是屏幕(lv_scr_act()
),因此坐标直接对应屏幕的像素位置。
LVGL对齐设置(alignment)
// 创建一个矩形对象(父对象为屏幕)
lv_obj_t *obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 200, 100); // 尺寸:200x100px//参照父对象对齐完全居中
lv_obj_set_align(obj,LV_ALIGN_CENTER);//参照父对象对齐再偏移,在父对象(屏幕)中完全居中,X轴右移10px,Y轴上移5px
lv_obj_align(obj, LV_ALIGN_CENTER, 10, -5); // 最终位置:屏幕中心(+10, -5)
// 创建参考对象(按钮)
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 50);
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0); // 按钮在屏幕中心
lv_obj_t *btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "but");
lv_obj_align(btn_label, LV_ALIGN_CENTER, 0, 0); // 文本在按钮中心// 创建标签,在按钮右侧中间对齐(偏移10px)
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "text");
// 对齐方式:标签左中点 与 按钮右中点 对齐,X轴再右移10px
lv_obj_align_to(label, btn, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
对齐(Alignment) 是控制对象位置的核心方式之一,用于将对象相对于父对象或其他对象精确定位(如居中、靠左、右上角对齐等),无需手动计算坐标。对齐设置通过一组直观的 API 实现,灵活适配各种布局需求。
对齐的本质是:通过指定 参考点和对象自身的对齐点,让两者重合(可加偏移量微调)。
- 参考点:可以是父对象的边缘 / 中心(如父对象的左上角、中心点),或其他对象的边缘 / 中心。
- 对象自身的对齐点:对象自身的边缘 / 中心(如对象的右下角、中点)。
LVGL样式设置(styles)
样式(Styles) 是控制 UI 元素外观的核心机制,用于定义对象的颜色、边框、圆角、文本属性等视觉特征。与直接修改对象属性不同,样式具有复用性(多个对象可共用同一样式)、可叠加性(多个样式可组合作用于同一对象)和可继承性(子对象可继承父对象样式),极大简化了 UI 外观管理。
一、样式的核心概念
样式本质:一个独立的lv_style_t结构体,存储外观属性(如背景色、文本大小等),与对象分离。
作用对象:所有 LVGL 组件(按钮、标签、弧等)都可应用样式,通过样式统一控制外观。
核心优势:修改样式即可批量更新所有应用该样式的对象,无需逐个调整,适合主题切换、统一 UI 风格。
二、样式的基本使用流程
LVGL 样式使用遵循 “初始化→设置属性→应用到对象” 三步流程,以下是完整示例:
// 1. 定义样式变量(用static修饰,确保生命周期与对象一致)
static lv_style_t my_style;// 2. 初始化样式(必须调用,重置结构体避免随机值)
lv_style_init(&my_style);// 3. 设置样式属性(如背景色、文本色、边框等)
lv_style_set_bg_color(&my_style, lv_color_hex(0x007FFF)); // 背景色:亮蓝色
lv_style_set_radius(&my_style, 8); // 圆角:8px
lv_style_set_border_width(&my_style, 2); // 边框宽度:2px
lv_style_set_border_color(&my_style, lv_color_hex(0x0059B2)); // 边框色:深蓝色
lv_style_set_text_color(&my_style, lv_color_white()); // 文本色:白色// 4. 创建对象并应用样式
lv_obj_t *obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 200, 100);
lv_obj_center(obj);
// 将样式应用到对象,0为默认状态,添加即生效
lv_obj_add_style(obj, &my_style, 0);//普通样式,可共享, 复用性(多对象共用)、叠加性(多样式组合)、状态关联性(不同状态不同样式)、继承性(子对象继承父样式)。
// 创建一个容器对象
lv_obj_t *cont = lv_obj_create(lv_scr_act());
lv_obj_set_size(cont, 200, 150);
lv_obj_center(cont);// 直接设置容器背景色为红色(0xFF0000),按下状态生效
lv_obj_set_style_bg_color(cont, lv_color_hex(0xFF0000), LV_STATE_PRESSED);
本地样式(Local Styles) 指的是仅为特定对象(或其直接子对象)定义和应用的样式,不被其他无关对象复用(不共享),主要用于满足单个对象的个性化外观需求。与 “全局样式”(多个对象共用的通用样式)相比,本地样式更侧重 “针对性定制”,适合实现特殊 UI 元素的独特外观。
// 创建一个容器对象(父对象为当前活动屏幕)
lv_obj_t *cont = lv_obj_create(lv_scr_act());
// 设置容器尺寸为 200px(宽)× 150px(高)
lv_obj_set_size(cont, 200, 150);
// 将容器在屏幕中居中对齐
lv_obj_center(cont);// 设置容器边框颜色:在默认状态(LV_STATE_DEFAULT)下为绿色(0x56c94c 对应浅绿)
// 参数说明:目标对象(cont)、颜色值(lv_color_hex转换的绿色)、生效状态(默认状态)
lv_obj_set_style_border_color(cont, lv_color_hex(0x56c94c), LV_STATE_DEFAULT);// 设置容器边框宽度:在默认状态下为 3px(数值越大边框越粗,0为无边框)
// 参数说明:目标对象(cont)、宽度值(3px)、生效状态(默认状态)
lv_obj_set_style_border_width(cont, 3, LV_STATE_DEFAULT);// 设置容器边框透明度:在默认状态下为完全不透明(LV_OPA_100 等价于 255,0为完全透明)
// 参数说明:目标对象(cont)、透明度值(LV_OPA_100)、生效状态(默认状态)
lv_obj_set_style_border_opa(cont, LV_OPA_100, LV_STATE_DEFAULT);
#include "ptm_demo1.h"
#include "stdio.h"// 静态回调函数声明:滑块值变化时更新上层文本透明度
static void slider_event_cb(lv_event_t *e);void ptm_demo(void)
{// 创建底层文本(被覆盖的文本)lv_obj_t *bottom_label = lv_label_create(lv_scr_act());lv_label_set_text(bottom_label, "down text");lv_obj_set_style_text_color(bottom_label, lv_color_hex(0x0000FF), 0); // 深蓝色lv_obj_set_style_text_opa(bottom_label, LV_OPA_100, 0); // 完全不透明lv_obj_align(bottom_label, LV_ALIGN_CENTER, 0, 0);// 创建上层文本(覆盖的文本)lv_obj_t *top_label = lv_label_create(lv_scr_act());lv_label_set_text(top_label, "top text");lv_obj_set_style_text_color(top_label, lv_color_hex(0xFF0000), 0); // 红色lv_obj_set_style_text_opa(top_label, LV_OPA_50, 0); // 初始透明度50%lv_obj_align(top_label, LV_ALIGN_CENTER, 0, 0); // 与底层文本重叠// ----------------新增滑块控制部分----------------// 创建滑块(用于调节上层文本透明度)lv_obj_t *slider = lv_slider_create(lv_scr_act());lv_obj_set_width(slider, 200); // 设置滑块宽度lv_slider_set_value(slider, 50, LV_ANIM_OFF); // 初始值50(对应50%透明度)lv_obj_align(slider, LV_ALIGN_CENTER, 0, 100); // 位于文本下方100px// 注册滑块事件:值变化时触发回调// 传递top_label作为用户数据,避免使用全局变量lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, top_label);// 添加滑块说明标签lv_obj_t *slider_label = lv_label_create(lv_scr_act());lv_label_set_text(slider_label, "opaset");lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_TOP_MID, 0, -10); // 滑块上方10px
}// 滑块事件回调函数:更新上层文本透明度
static void slider_event_cb(lv_event_t *e)
{lv_obj_t *slider = lv_event_get_target(e); // 获取滑块对象lv_obj_t *top_label = lv_event_get_user_data(e); // 获取上层文本对象// 获取滑块当前值(0~100)int32_t slider_val = lv_slider_get_value(slider);// 转换为LVGL透明度值(0~255)lv_opa_t opacity = (lv_opa_t)(slider_val * 255 / 100);// 更新上层文本透明度lv_obj_set_style_text_opa(top_label, opacity, 0);
}
LVGL事件设置(events)
在 LVGL 中,事件(Events) 是处理用户交互(如点击、滑动)或系统状态变化(如组件值修改、显示隐藏)的核心机制。通过事件,我们可以为 UI 组件(按钮、滑块、列表等)绑定 “响应逻辑”,实现交互功能(如点击按钮切换文本、拖动滑块调节参数)。
一、事件的核心概念
- 事件(Event):触发某种行为的 “信号”,例如 “按钮被按下”“滑块值变化”“文本被点击”。
- 事件源(Event Source):触发事件的组件(如按钮、滑块)。
- 回调函数(Callback Function):事件触发时执行的自定义函数,用于实现具体的响应逻辑。
- 事件类型(Event Type):区分事件的类别(如按下、释放、值变化),决定回调函数何时被调用。
二、常见事件类型(Event Types)
LVGL 定义了多种事件类型,覆盖输入交互、状态变化、组件特定行为等场景,以下是开发中最常用的类型:
事件类型 | 触发时机 | 适用组件 |
---|---|---|
LV_EVENT_CLICKED | 组件被点击(按下后释放) | 按钮、标签、容器等 |
LV_EVENT_PRESSED | 组件被按下(未释放) | 所有可交互组件 |
LV_EVENT_RELEASED | 组件被释放(按下后抬起) | 所有可交互组件 |
LV_EVENT_VALUE_CHANGED | 组件的值发生变化 | 滑块、开关、下拉框、计数器 |
LV_EVENT_FOCUSED | 组件获得焦点(如键盘选中) | 输入框、按钮等 |
LV_EVENT_DEFOCUSED | 组件失去焦点 | 输入框、按钮等 |
LV_EVENT_DELETED | 组件被销毁前 | 所有组件 |
LV_EVENT_SCROLLED | 组件滚动时(如列表、页面容器) | 滚动容器、列表、表格 |
三、事件设置的核心流程
为组件绑定事件的流程分为 3 步:
- 定义回调函数:编写事件触发时执行的逻辑;
- 注册事件:将回调函数与组件、事件类型绑定;
- (可选)传递用户数据:在回调中使用额外参数(如关联的其他组件)。
四、详细实现步骤(附示例代码)
1. 定义事件回调函数
回调函数的固定原型为:
static void event_cb(lv_event_t *e);
通过lv_event_t *e
参数,可获取事件相关信息(事件源、用户数据等)。
2. 注册事件(核心 API)
使用lv_obj_add_event_cb
为组件注册事件,API 原型:
void lv_obj_add_event_cb(lv_obj_t *obj, lv_event_cb_t event_cb, lv_event_code_t filter, void *user_data);
obj
:目标组件(事件源);event_cb
:回调函数;filter
:事件类型(如LV_EVENT_CLICKED
,可多个类型用|
组合,如LV_EVENT_PRESSED | LV_EVENT_RELEASED
);user_data
:传递给回调的自定义数据(如关联的其他组件指针)。
3. 完整示例 1:按钮点击事件
实现 “点击按钮,切换标签文本” 的功能:
#include "lvgl.h"// 1. 定义回调函数:处理按钮点击事件
static void btn_click_cb(lv_event_t *e) {// 获取传递的用户数据(这里是标签对象)lv_obj_t *label = lv_event_get_user_data(e);// 判断当前标签文本,切换内容const char *curr_text = lv_label_get_text(label);if (strcmp(curr_text, "Hello LVGL") == 0) {lv_label_set_text(label, "Button Clicked!");} else {lv_label_set_text(label, "Hello LVGL");}
}void lv_demo_event_btn(void) {// 创建标签(用于显示文本)lv_obj_t *label = lv_label_create(lv_scr_act());lv_label_set_text(label, "Hello LVGL");lv_obj_align(label, LV_ALIGN_CENTER, 0, -50); // 标签在屏幕中心上方50px// 创建按钮(事件源)lv_obj_t *btn = lv_btn_create(lv_scr_act());lv_obj_set_size(btn, 120, 50);lv_obj_align(btn, LV_ALIGN_CENTER, 0, 50); // 按钮在屏幕中心下方50px// 给按钮添加文本lv_obj_t *btn_label = lv_label_create(btn);lv_label_set_text(btn_label, "Click Me");lv_obj_center(btn_label);// 2. 注册事件:按钮点击时触发btn_click_cb,传递label作为用户数据lv_obj_add_event_cb(btn, btn_click_cb, LV_EVENT_CLICKED, label);
}// 在main函数中调用
// lv_demo_event_btn();
4. 完整示例 2:滑块值变化事件
实现 “拖动滑块,实时更新标签显示滑块值” 的功能:
#include "lvgl.h"// 1. 定义回调函数:处理滑块值变化事件
static void slider_change_cb(lv_event_t *e) {// 获取事件源(滑块)lv_obj_t *slider = lv_event_get_target(e);// 获取传递的用户数据(显示值的标签)lv_obj_t *value_label = lv_event_get_user_data(e);// 获取滑块当前值(0~100,默认范围)int32_t slider_val = lv_slider_get_value(slider);// 格式化文本,更新标签char buf[20];sprintf(buf, "Slider Value: %d", slider_val);lv_label_set_text(value_label, buf);
}void lv_demo_event_slider(void) {// 创建显示值的标签lv_obj_t *value_label = lv_label_create(lv_scr_act());lv_label_set_text(value_label, "Slider Value: 50");lv_obj_align(value_label, LV_ALIGN_CENTER, 0, -50);// 创建滑块(事件源)lv_obj_t *slider = lv_slider_create(lv_scr_act());lv_obj_set_width(slider, 200);lv_slider_set_value(slider, 50, LV_ANIM_OFF); // 初始值50lv_obj_align(slider, LV_ALIGN_CENTER, 0, 50);// 2. 注册事件:滑块值变化时触发回调,传递value_label作为用户数据lv_obj_add_event_cb(slider, slider_change_cb, LV_EVENT_VALUE_CHANGED, value_label);
}// 在main函数中调用
// lv_demo_event_slider();
五、事件相关常用 API
除了注册事件,LVGL 还提供了一系列 API 用于获取事件信息或管理事件:
API 函数 | 作用 | 示例 |
---|---|---|
lv_event_get_target(e) | 获取事件源(触发事件的组件) | lv_obj_t *slider = lv_event_get_target(e); |
lv_event_get_user_data(e) | 获取注册事件时传递的用户数据 | lv_obj_t *label = lv_event_get_user_data(e); |
lv_event_get_code(e) | 获取当前触发的事件类型 | lv_event_code_t code = lv_event_get_code(e); |
lv_obj_remove_event_cb(obj, cb) | 移除组件的指定回调函数 | lv_obj_remove_event_cb(btn, btn_click_cb); |
lv_obj_remove_all_event_cbs(obj) | 移除组件的所有事件回调 | lv_obj_remove_all_event_cbs(btn); |
六、关键注意事项
-
回调函数生命周期:回调函数需定义为
static
(或全局),避免函数地址失效(局部函数在栈上,生命周期结束后会被释放)。 -
用户数据有效性:传递给
user_data
的指针(如组件指针)需确保在回调执行时未被销毁,否则会导致野指针错误。 -
多事件类型绑定:可通过
|
为一个回调绑定多个事件类型,例如:// 按钮按下和释放时都触发回调 lv_obj_add_event_cb(btn, btn_cb, LV_EVENT_PRESSED | LV_EVENT_RELEASED, NULL);
在回调中可通过
lv_event_get_code(e)
区分具体事件类型:static void btn_cb(lv_event_t *e) {lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_PRESSED) {// 按下时逻辑} else if (code == LV_EVENT_RELEASED) {// 释放时逻辑} }
-
避免耗时操作:回调函数中不要执行耗时逻辑(如复杂计算、延时),否则会阻塞 LVGL 主循环,导致 UI 卡顿。
七、总结
LVGL 事件系统的核心是 “组件 + 事件类型 + 回调函数” 的绑定模式,通过以下步骤即可实现交互功能:
- 编写回调函数,定义事件响应逻辑;
- 用
lv_obj_add_event_cb
将回调与组件、事件类型绑定; - (可选)通过
user_data
传递关联数据,实现组件间联动。
掌握事件设置是 LVGL 开发的基础,无论是简单的按钮点击,还是复杂的滚动、输入交互,都依赖事件机制实现。
LVGL标签部件(lable)
在 LVGL 中,标签(Label) 是用于显示文本的基础部件,支持静态文本、动态数据、特殊符号(如图标)等,是 UI 界面中最常用的组件之一。标签本身不具备交互功能(如点击),但可以作为其他组件(如按钮、列表项)的子元素,用于展示说明文字。
一、标签的核心特性
- 支持普通文本、格式化文本(如变量值)、UTF-8 编码(含中文、特殊字符);
- 可设置字体、颜色、大小、透明度、对齐方式等样式;
- 提供多种长文本处理模式(自动换行、裁剪、滚动显示等);
- 支持嵌入 LVGL 内置符号(如箭头、图标)。
二、创建标签的基本方法
使用 lv_label_create(parent)
函数创建标签,参数为父对象(通常是屏幕 lv_scr_act()
或其他容器)。
#include "lvgl.h"void lv_demo_label_basic(void) {// 创建一个标签,父对象为当前屏幕lv_obj_t *label = lv_label_create(lv_scr_act());// 设置标签文本lv_label_set_text(label, "Hello LVGL!");// 对齐到屏幕中心lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
三、文本内容设置
标签的核心功能是显示文本,LVGL 提供了多种设置文本的方式:
1. 设置普通文本
使用 lv_label_set_text(label, text)
直接设置字符串:
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "这是一段普通文本"); // 支持中文(需确保字体包含中文字符)
2. 设置格式化文本
使用 lv_label_set_text_fmt(label, fmt, ...)
格式化文本(类似 printf
),常用于显示变量值:
lv_obj_t *label = lv_label_create(lv_scr_act());
int temp = 25;
float humidity = 60.5;
// 格式化显示温度和湿度
lv_label_set_text_fmt(label, "温度: %d℃ 湿度: %.1f%%", temp, humidity);
3. 获取当前文本
使用 lv_label_get_text(label)
获取标签当前显示的文本:
const char *text = lv_label_get_text(label);
printf("当前文本: %s\n", text); // 打印到控制台
四、样式设置(外观定制)
通过 lv_obj_set_style_xxx()
系列函数可定制标签的外观,常用样式包括:
1. 文本颜色
// 设置文本颜色为红色(0xFF0000)
lv_obj_set_style_text_color(label, lv_color_hex(0xFF0000), 0);// 1. 创建标签对象(父对象为当前屏幕)lv_obj_t *label = lv_label_create(lv_scr_act());// 2. 开启“重新着色”功能(必须先开启,否则#RRGGBB会被当作普通文本)lv_label_set_recolor(label, true);// 3. 设置文本:用#ff0000标记红色文本段,用#闭合lv_label_set_text(label, "Hello #ff0000 LVGL# World!");// 4. 对齐标签到屏幕中心(可选,用于布局)lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);lv_obj_t *label = lv_label_create(lv_scr_act());lv_label_set_text(label, "text");// 起始背景色(蓝色)lv_obj_set_style_bg_color(label, lv_color_hex(0x0000FF), 0);// 渐变目标色(青色)lv_obj_set_style_bg_grad_color(label, lv_color_hex(0x00FFFF), 0);// 渐变方向:水平(从左到右)lv_obj_set_style_bg_grad_dir(label, LV_GRAD_DIR_HOR, 0);lv_obj_set_style_bg_opa(label, LV_OPA_100, 0);lv_obj_set_style_pad_all(label, 10, 0);lv_obj_set_style_radius(label, 8, 0); // 轻微圆角lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
2. 字体与大小
LVGL 默认提供多种字体(如 lv_font_montserrat_12
、lv_font_montserrat_16
等),也支持自定义字体:
// 设置字体(需包含对应字体头文件)
#include "lv_font_montserrat_24.h"
lv_obj_set_style_text_font(label, &lv_font_montserrat_24, 0); // 24号字体
3. 透明度
// 设置透明度为50%(0~255,0完全透明,255完全不透明)
lv_obj_set_style_text_opa(label, LV_OPA_50, 0);lv_obj_t *label = lv_label_create(lv_scr_act());lv_label_set_text(label, "text");// 设置背景色(浅蓝色)lv_obj_set_style_bg_color(label, lv_color_hex(0xCCE5FF), 0);// 背景完全不透明lv_obj_set_style_bg_opa(label, LV_OPA_100, 0);// 内边距:上下左右各10px(文本与背景边缘的距离)lv_obj_set_style_pad_all(label, 10, 0);// 对齐到屏幕中心lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
4. 对齐方式
文本在标签内的对齐(水平 / 垂直):
// 水平对齐:左对齐(默认)、居中、右对齐
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); // 水平居中
5. 行间距与字间距
// 设置行间距(多行文本文字间的距离)
lv_obj_set_style_text_line_space(label, 10, 0); // 行间距10px// 设置字间距(字符间的距离)
lv_obj_set_style_text_letter_space(label, 2, 0); // 字间距2px
五、长文本处理
当文本长度超过标签宽度时,LVGL 提供 4 种处理模式(通过 lv_label_set_long_mode()
设置):
模式 | 效果描述 |
---|---|
LV_LABEL_LONG_WRAP | 自动换行(默认模式),文本超出宽度时换行 |
LV_LABEL_LONG_CLIP | 裁剪超出部分,只显示标签范围内的文本 |
LV_LABEL_LONG_SCROLL | 水平滚动(一次滚动到底),适用于单行文本 |
LV_LABEL_LONG_SCROLL_CIRCULAR | 循环滚动(跑马灯效果),适用于单行文本 |
示例:长文本滚动(跑马灯效果)
void lv_demo_label_long_text(void) {// 创建标签,设置固定宽度(触发长文本处理)lv_obj_t *label = lv_label_create(lv_scr_act());lv_obj_set_width(label, 200); // 标签宽度200px// 设置超长文本lv_label_set_text(label, "I am ptm mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.................");// 设置长文本模式为循环滚动lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);// 对齐到屏幕中心lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
六、特殊功能:嵌入符号(图标)
LVGL 内置了一套符号字体(如箭头、勾选框、电池图标等),可直接在文本中使用,语法为 LV_SYMBOL_XXX
:
void lv_demo_label_symbols(void) {lv_obj_t *label = lv_label_create(lv_scr_act());// 组合文本和符号(符号本质是特殊字符)lv_label_set_text(label, LV_SYMBOL_OK " 操作成功\n"LV_SYMBOL_WARNING " 注意:请检查参数\n"LV_SYMBOL_BATTERY_FULL " 电量充足");// 对齐到屏幕中心lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
常用符号:LV_SYMBOL_OK
(√)、LV_SYMBOL_CLOSE
(×)、LV_SYMBOL_UP
(↑)、LV_SYMBOL_DOWN
(↓)、LV_SYMBOL_WIFI
(WiFi 图标)等。
七、动态更新文本
在事件回调中(如按钮点击、滑块变化)动态更新标签文本,是交互场景的常见需求:
// 滑块值变化时,更新标签显示当前值
static void slider_event_cb(lv_event_t *e) {lv_obj_t *slider = lv_event_get_target(e);lv_obj_t *label = lv_event_get_user_data(e);int32_t val = lv_slider_get_value(slider);lv_label_set_text_fmt(label, "当前值: %d", val); // 动态更新文本
}void lv_demo_label_dynamic(void) {// 创建显示值的标签lv_obj_t *label = lv_label_create(lv_scr_act());lv_label_set_text(label, "当前值: 50");lv_obj_align(label, LV_ALIGN_CENTER, 0, -50);// 创建滑块lv_obj_t *slider = lv_slider_create(lv_scr_act());lv_slider_set_value(slider, 50, LV_ANIM_OFF);lv_obj_align(slider, LV_ALIGN_CENTER, 0, 50);// 绑定事件:滑块值变化时更新标签lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, label);
}
八、注意事项
-
字体支持:中文、日文等特殊字符需要使用包含对应字符集的字体(LVGL 默认字体可能不含中文字符),需在工程中配置自定义字体。
-
性能优化:频繁更新标签文本(如每秒多次)时,建议使用
lv_label_set_text_fmt
而非拼接字符串,减少内存开销。 -
文本长度限制:标签文本默认存储在 LVGL 的动态内存中,超长文本可能占用较多内存,需注意内存使用。
九、总结
标签(Label)是 LVGL 中最基础的文本显示组件,通过以下核心操作可满足大部分文本展示需求:
- 用
lv_label_create()
创建标签,lv_label_set_text()
设置文本; - 用
lv_obj_set_style_xxx()
定制颜色、字体、对齐等样式; - 用
lv_label_set_long_mode()
处理长文本(换行、滚动等); - 结合事件系统实现文本动态更新。
掌握标签的使用是构建 LVGL 界面的基础,无论是简单的提示文字还是复杂的动态数据展示,都离不开标签部件。
LVGL按钮部件(button)
LVGL 的按钮部件是实现用户交互的核心组件,分为基础按钮(lv_btn
)、 按钮矩阵(lv_btnmatrix
)和图片按钮(lv_imgbtn
)三类,可满足不同交互与视觉需求。
一、基础按钮(lv_btn
):核心交互单元
基础按钮是最常用的交互组件,默认呈 “圆角矩形”,需结合标签(lv_label
)显示文本,支持 “按下 / 释放”“选中 / 取消” 等状态切换。
1. 创建与文本显示
按钮本身不直接支持文本,需通过 “标签作为子对象” 实现:
// 1. 创建基础按钮(父对象为当前屏幕)
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 120, 50); // 设置按钮尺寸
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0); // 屏幕中心对齐// 2. 创建标签(作为按钮的子对象,显示文本)
lv_obj_t *btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "Click Me"); // 设置按钮文本
lv_obj_center(btn_label); // 标签在按钮内居中
2. 状态管理
按钮支持 5 种核心状态(枚举 lv_btn_state_t
),可通过 API 控制或查询状态:
状态枚举 | 描述 |
---|---|
LV_STATE_DEFAULT | 释放(默认未按下状态) |
LV_STATE_PRESSED | 按下(按压中) |
LV_STATE_CHECKED | 切换后释放(选中且未按) |
LV_STATE_CHECKED | LV_STATE_PRESSED | 切换后按下(选中且按压) |
LV_STATE_DISABLED | 禁用(灰色,不可交互) |
lv_obj_t *btn = lv_btn_create(lv_scr_act());lv_obj_set_size(btn,100,50);lv_obj_set_align(btn,LV_ALIGN_CENTER);lv_obj_add_flag(btn,LV_OBJ_FLAG_CHECKABLE);
3. 样式定制
通过 lv_obj_set_style_xxx
系列函数,可定制按钮的背景、边框、圆角等样式(支持不同状态下的样式区分):
// 释放状态:背景色为蓝色
lv_obj_set_style_bg_color(btn, lv_color_hex(0x3A89F4), LV_STATE_CHECKED);
// 按下状态:背景色为深蓝色
lv_obj_set_style_bg_color(btn, lv_color_hex(0x2A69C4), LV_STATE_PRESSED);
// 圆角:让按钮更圆润(半径10px)
lv_obj_set_style_radius(btn, 10, 0);
// 边框:宽度2px,颜色白色
lv_obj_set_style_border_width(btn, 2, 0);
lv_obj_set_style_border_color(btn, lv_color_white(), 0);
4. 事件处理
通过 lv_obj_add_event_cb
绑定事件回调,响应 “点击”“状态变化” 等交互:
static void btn_event_cb(lv_event_t *e) {lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_CLICKED) {printf("按钮被点击\n");} else if (code == LV_EVENT_VALUE_CHANGED) {printf("按钮状态切换(选中/取消)\n");}
}// 绑定事件(支持 LV_EVENT_ALL 监听所有事件)
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);
二、按钮矩阵(lv_btnmatrix
):多按钮组合
按钮矩阵用于创建多行多列的按钮组,支持换行、宽度比例、互斥选中、文本重着色等高级功能,适合 “键盘”“选项组” 等场景。
1. 布局与映射(Map)
通过字符串数组定义按钮布局(用 "\n"
换行,空字符串 ""
结尾):
// 定义按钮映射:btn1 换行后,btn2、btn3 在第二行
const static char *btn_map[] = {"btn1", "\n", "btn2", "btn3", ""};lv_obj_t *btnm = lv_btnmatrix_create(lv_scr_act());
lv_btnmatrix_set_map(btnm, btn_map); // 设置按钮布局
lv_obj_align(btnm, LV_ALIGN_CENTER, 0, 0); // 屏幕中心对齐
2. 核心特性
- 按钮宽度:通过
lv_btnmatrix_set_btn_width
设置 “相对宽度”(例:1:1:2
表示三个按钮占比 25%、25%、50%)。 - 互斥选中:多个按钮设为
LV_BTNMATRIX_CTRL_CHECKABLE
后,可通过逻辑实现 “单选”(选中一个时,其他自动取消)。 - 文本重着色:开启
LV_BTNMATRIX_CTRL_RECOLOR
后,按钮文本可通过#RRGGBB 文本#
格式设置颜色。
// 1. 定义全局/静态映射数组(确保生命周期)
const static char *btn_map[] = {"btn1", "\n", "btn2", "btn3", ""};
const static char *colored_map[] = {"#FF0000 RedBtn#", "GreenBtn", ""}; // 静态全局,避免释放void ptm_demo(void) {lv_obj_t *btnm = lv_btnmatrix_create(lv_scr_act());// 2. 若需更换映射,建议先设置新映射,再针对新映射的按钮设置属性lv_btnmatrix_set_map(btnm, colored_map); // 先设置目标映射// 3. 针对新映射的按钮设置属性(colored_map 有2个按钮,索引0和1)// 为第0个按钮(RedBtn)设置宽度和重着色功能lv_btnmatrix_set_btn_width(btnm, 0, 2); // 针对新映射的第0个按钮lv_btnmatrix_set_btn_ctrl(btnm, 0, LV_BUTTONMATRIX_CTRL_RECOLOR); // 开启着色// (可选)为第0个按钮设置可切换lv_btnmatrix_set_btn_ctrl(btnm, 0, LV_BTNMATRIX_CTRL_CHECKABLE);lv_obj_align(btnm, LV_ALIGN_CENTER, 0, 0);
}
3. 事件与 API
常用事件 LV_EVENT_VALUE_CHANGED
(按钮点击 / 切换时触发),结合 API 获取选中按钮:
static void btnm_event_cb(lv_event_t *e) {if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {lv_obj_t *btnm = lv_event_get_target(e);uint16_t id = lv_btnmatrix_get_selected_btn(btnm); // 获取选中按钮索引const char *txt = lv_btnmatrix_get_btn_text(btnm, id); // 获取按钮文本printf("选中按钮 #%d: %s\n", id, txt);}
}lv_obj_add_event_cb(btnm, btnm_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
三、图片按钮(lv_imgbtn
):自定义视觉按钮
图片按钮通过图片资源展示不同状态(释放、按下、禁用等),适合 “游戏按钮”“主题化 UI” 等视觉定制场景。
1. 准备图片资源
需将图片转换为 LVGL 支持的C 数组(推荐使用 LVGL 官方工具:Online Image Converter)。
2. 创建与状态图片设置
// 1. 创建图片按钮
lv_obj_t *imgbtn = lv_imgbtn_create(lv_scr_act());
lv_obj_align(imgbtn, LV_ALIGN_CENTER, 0, 0); // 屏幕中心对齐// 2. 设置不同状态的图片(使用 LVGL 8.3 通用状态枚举)
// 释放状态(默认未按下)
lv_imgbtn_set_src(imgbtn, LV_STATE_DEFAULT, &my_img_rel, NULL);
// 按下状态
lv_imgbtn_set_src(imgbtn, LV_STATE_PRESSED, &my_img_pr, NULL);
// 禁用状态(可选)
lv_imgbtn_set_src(imgbtn, LV_STATE_DISABLED, &my_img_ina, NULL);// (可选)如果需要设置选中状态的图片(如可切换的图片按钮)
// lv_obj_add_flag(imgbtn, LV_OBJ_FLAG_CHECKABLE); // 开启可切换功能
// lv_imgbtn_set_src(imgbtn, LV_STATE_CHECKED, &my_img_checked, NULL); // 选中状态图片
3. 事件与交互
图片按钮的事件处理与基础按钮一致,可绑定 LV_EVENT_CLICKED
等事件:
LVGL按钮部件(button)
四、总结与最佳实践
按钮类型 | 适用场景 | 核心优势 |
---|---|---|
基础按钮 | 简单交互(如 “确认”“取消”) | 轻量、易与标签结合 |
按钮矩阵 | 多按钮组合(如键盘、选项组) | 批量管理、复杂布局支持 |
图片按钮 | 视觉定制化(如游戏、主题 UI) | 自定义外观、多状态视觉反馈 |
最佳实践:
- 基础按钮需手动结合标签显示文本,确保文本与按钮对齐;
- 按钮矩阵的 “互斥选中” 需明确业务逻辑,避免交互歧义;
- 图片按钮的图片资源需提前转换为 LVGL 格式,且需评估内存占用(大图片可能消耗较多 RAM)。
LVGL开关部件(switch)
在 LVGL中,开关部件(lv_switch
)是一种模拟物理 toggle 开关的交互组件,用于实现二元状态(开启 / 关闭)切换,广泛应用于设置界面、功能启停等场景。
一、核心概念与结构
LVGL的开关由 3 个核心视觉部分(LV_PART
)组成,对应不同的样式控制:
LV_PART_MAIN
:开关的基础背景(关闭状态时可见),通常为圆角矩形。LV_PART_INDICATOR
:状态指示器(开启状态时可见),覆盖在MAIN
之上,显示 "已开启" 的背景。LV_PART_KNOB
:滑动块(旋钮),随状态切换移动,是用户交互的核心视觉元素。
这三部分独立可控,通过样式系统可分别定制颜色、大小、圆角等属性。
二、基础用法:创建
使用lv_switch_create(parent)
函数创建开关,父对象通常为屏幕(lv_scr_act()
)或容器:
#include "lvgl.h"void switch_demo_init(void) {// 创建开关,父对象为当前活动屏幕lv_obj_t * switch1 = lv_switch_create(lv_scr_act());// 设置位置(相对于父对象的x、y坐标)lv_obj_set_pos(switch1, 100, 100);// 设置大小(可选,默认有自适应尺寸)lv_obj_set_size(switch1, 60, 30); // 宽60px,高30px
}
三、事件处理:监听状态变化
开关状态变化时会触发LV_EVENT_VALUE_CHANGED
事件,通过注册回调函数可捕获状态切换并执行逻辑(如控制硬件、更新 UI)。
示例:监听开关状态
// 事件回调函数
static void switch_event_handler(lv_event_t * e) {lv_obj_t * switch_obj = lv_event_get_target(e); // 获取触发事件的开关对象lv_event_code_t code = lv_event_get_code(e); // 获取事件类型if (code == LV_EVENT_VALUE_CHANGED) {bool is_on = lv_obj_get_state(switch_obj);if (is_on) {LV_LOG_USER("开关已开启");// 执行开启逻辑(如点亮LED、启动功能)} else {LV_LOG_USER("开关已关闭");// 执行关闭逻辑(如熄灭LED、停止功能)}}
}void ptm_demo(void)
{lv_obj_t * switch1 = lv_switch_create(lv_scr_act());lv_obj_set_pos(switch1, 100, 100);// 注册事件:监听所有事件,回调函数为switch_event_handlerlv_obj_add_event_cb(switch1, switch_event_handler, LV_EVENT_ALL, NULL);
}
关键 API:
lv_event_get_target(e)
:从事件对象中获取触发事件的开关部件。lv_event_get_code(e)
:获取事件类型(如LV_EVENT_VALUE_CHANGED
)。
四、样式定制:打造个性化开关
LVGL的样式系统通过lv_style_t
结构体和lv_style_set_*
函数配置样式,可分别定制开关的 3 个部分(MAIN
/INDICATOR
/KNOB
)。
示例:定制深色模式开关
void switch_style_demo(void) {lv_obj_t * switch1 = lv_switch_create(lv_scr_act());lv_obj_set_pos(switch1, 100, 100);lv_obj_set_size(switch1, 60, 30); // 宽60,高30// 1. 初始化样式static lv_style_t style_main; // 关闭状态背景static lv_style_t style_indic; // 开启状态指示器static lv_style_t style_knob; // 滑动块lv_style_init(&style_main);lv_style_init(&style_indic);lv_style_init(&style_knob);// 2. 配置样式// 关闭状态背景:深灰色圆角矩形lv_style_set_bg_color(&style_main, lv_color_hex(0x333333)); // 背景色lv_style_set_radius(&style_main, 15); // 圆角(高的一半,实现胶囊形)lv_style_set_border_width(&style_main, 0); // 无边框// 开启状态指示器:绿色背景lv_style_set_bg_color(&style_indic, lv_color_hex(0x00cc66)); // 指示器颜色lv_style_set_radius(&style_indic, 15); // 同主背景圆角// 滑动块:白色圆形,带阴影lv_style_set_bg_color(&style_knob, lv_color_hex(0xffffff)); // 滑动块颜色lv_style_set_radius(&style_knob, LV_RADIUS_CIRCLE); // 圆形lv_style_set_shadow_color(&style_knob, lv_color_hex(0x000000)); // 阴影色lv_style_set_shadow_width(&style_knob, 2); // 阴影宽度lv_style_set_shadow_offset_y(&style_knob, 1); // 阴影Y偏移// 3. 应用样式到开关的对应部分lv_obj_add_style(switch1, &style_main, LV_PART_MAIN);lv_obj_add_style(switch1, &style_indic, LV_PART_INDICATOR);lv_obj_add_style(switch1, &style_knob, LV_PART_KNOB);
}
样式要点:
- 圆角设置:若要实现 "胶囊形" 开关,
radius
应设为高度的一半(如高 30 则 radius=15)。 - 滑动块大小:默认自动适配,可通过
lv_style_set_size(&style_knob, 26, 26)
手动调整(通常略小于开关高度)。 - 状态联动:开启时
INDICATOR
显示,关闭时MAIN
显示,无需手动控制显隐。
// 创建开关部件:父对象为当前活动屏幕(lv_scr_act()返回当前显示的屏幕对象)
// 返回值为创建的开关对象指针,赋值给switch1
lv_obj_t * switch1 = lv_switch_create(lv_scr_act());// 设置开关的位置:相对于父对象(屏幕)的x坐标100,y坐标100
lv_obj_set_pos(switch1, 100, 100);// 设置样式:为开关的"指示器部分(LV_PART_INDICATOR)"在"选中状态(LV_STATE_CHECKED)"下的背景色
// lv_color_hex(0x0ffff0)表示十六进制颜色值(此处为青色)
// 效果:当开关处于开启状态时,指示器背景显示为青色
lv_obj_set_style_bg_color(switch1, lv_color_hex(0x0ffff0), LV_STATE_CHECKED | LV_PART_INDICATOR);// 给开关添加"选中状态(LV_STATE_CHECKED)"
// 效果:开关变为开启状态(滑动块移到右侧,指示器显示)
lv_obj_add_state(switch1, LV_STATE_CHECKED);// 给开关同时添加"选中状态(LV_STATE_CHECKED)"和"禁用状态(LV_STATE_DISABLED)"
// 效果:开关保持开启状态,但变为禁用(无法通过用户交互改变状态,视觉上通常会变灰)
lv_obj_add_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED);// 清除开关的"选中状态(LV_STATE_CHECKED)"
// 效果:开关从开启状态变为关闭状态(滑动块移到左侧,指示器隐藏)
lv_obj_clear_state(switch1, LV_STATE_CHECKED);// 同时清除开关的"选中状态(LV_STATE_CHECKED)"和"禁用状态(LV_STATE_DISABLED)"
// 效果:开关恢复为关闭状态,且解除禁用(可通过用户交互改变状态)
lv_obj_clear_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED);
lv_obj_t * switch1;void event_cb(lv_event_t *e)
{lv_event_code_t code = lv_event_get_code(e);if(code == LV_EVENT_VALUE_CHANGED){if(lv_obj_has_state(switch1,LV_STATE_CHECKED))printf("on\n");elseprintf("off\n");}
}void ptm_demo(void)
{switch1 = lv_switch_create(lv_scr_act());lv_obj_set_pos(switch1, 100, 100);lv_obj_set_style_bg_color(switch1,lv_color_hex(0x0ffff0),LV_STATE_CHECKED|LV_PART_INDICATOR);lv_obj_add_state(switch1,LV_STATE_CHECKED);lv_obj_add_state(switch1,LV_STATE_CHECKED|LV_STATE_DISABLED);lv_obj_clear_state(switch1,LV_STATE_CHECKED);lv_obj_clear_state(switch1,LV_STATE_CHECKED|LV_STATE_DISABLED);lv_obj_add_event_cb(switch1,event_cb,LV_EVENT_VALUE_CHANGED,NULL);}
总结
LVGL 的开关部件结合样式系统可高度定制外观,事件机制方便与业务逻辑联动。实际开发中,可根据 UI 设计需求调整样式,并通过事件回调实现与硬件(如 GPIO 控制 LED)或其他 UI 组件的交互,是嵌入式 GUI 中实现二元状态切换的理想选择。
LVGL复选框部件(checkbox)
LVGL 中的复选框部件(lv_checkbox
)是用于实现 “多选” 功能的交互组件,由一个 “勾选框” 和可选的 “文本标签” 组成,支持 “选中”“未选中”“不确定”(可选)三种状态,广泛应用于设置面板、选项列表等场景。相比开关(lv_switch
),复选框更适合需要显示文本说明或支持多选项同时选择的场景。
一、基本结构
LVGL 复选框由两个核心视觉部分组成:
LV_PART_BOX
:勾选框(方形或圆形容器),用于显示选中状态(通常为对勾、圆点等标记)。LV_PART_LABEL
:文本标签,用于描述复选框的含义(如 “接收通知”“启用功能 A”)。
二、基本用法
#include "lvgl.h"void checkbox_basic_demo(void) {// 创建复选框,父对象为当前活动屏幕lv_obj_t * checkbox1 = lv_checkbox_create(lv_scr_act());// 设置文本标签(支持UTF-8字符,如中文)lv_checkbox_set_text(checkbox1, "接收推送通知");// 设置位置(x: 50, y: 50)lv_obj_set_pos(checkbox1, 50, 50);
}
// 创建复选框部件,父对象为当前活动屏幕(lv_scr_act()返回当前显示的屏幕)
// 返回值为创建的复选框对象指针,赋值给变量checkbox
lv_obj_t *checkbox = lv_checkbox_create(lv_scr_act());// 设置复选框的对齐方式:相对于父对象(屏幕)居中对齐
// LV_ALIGN_CENTER 表示水平和垂直方向都居中
lv_obj_set_align(checkbox, LV_ALIGN_CENTER);// 为复选框设置文本标签内容
// 文本会显示在勾选框右侧,描述该复选框的含义(此处为"checkbox")
lv_checkbox_set_text(checkbox, "checkbox");// 设置样式:为复选框在"选中状态(LV_STATE_CHECKED)"下的"列间距"(pad_column)
// 参数说明:
// - 50:间距值(单位为像素),控制勾选框(LV_PART_BOX)和文本标签(LV_PART_LABEL)之间的水平距离
// - LV_STATE_CHECKED:表示该样式仅在复选框处于选中状态时生效
// 效果:当复选框被勾选时,勾选框和文本之间的距离变为50像素(未选中时使用默认间距)
lv_obj_set_style_pad_column(checkbox, 50, LV_STATE_CHECKED);
LVGL进度条部件(bar)
LVGL 中的进度条部件(lv_bar
)用于直观展示任务进度、数值占比或状态变化(如音量、亮度调节),核心由 “背景” 和 “进度指示器” 两部分组成,支持水平 / 垂直方向、自定义范围及动态更新,是嵌入式 GUI 中展示进度类信息的常用组件。
一、基本结构
进度条由两个核心视觉部分(LV_PART
)构成:
LV_PART_MAIN
:进度条的背景容器,展示整个进度条的轮廓(如总长度 / 高度)。LV_PART_INDICATOR
:进度指示器,根据当前值动态显示填充长度(如完成的进度部分)。
二、基本用法:创建与进度控制
1. 创建进度条并设置基本属性
使用lv_bar_create(parent)
创建进度条,通过lv_bar_set_range
设置数值范围(默认 0~100),lv_bar_set_value
设置当前进度值:
#include "lvgl.h"void bar_basic_demo(void) {// 创建进度条,父对象为当前活动屏幕lv_obj_t * bar1 = lv_bar_create(lv_scr_act());// 设置进度条大小(宽200,高20):宽>高为水平方向lv_obj_set_size(bar1, 200, 20);// 设置位置(屏幕水平居中,y=100)lv_obj_set_pos(bar1, (LV_HOR_RES - 200)/2, 100);// 设置数值范围(默认0~100,此处示例改为0~200)lv_bar_set_range(bar1, 0, 200);// 设置当前进度值(带动画,500ms内平滑过渡到150)lv_obj_set_style_anim_time(bar1,500,LV_STATE_DEFAULT);lv_bar_set_value(bar1, 150, LV_ANIM_ON);}
2. 核心进度控制 API
函数原型 | 功能描述 | 示例 |
---|---|---|
void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max) | 设置进度条数值范围(默认 0~100) | lv_bar_set_range(bar1, 0, 500); |
void lv_bar_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) | 设置当前进度值(anim 控制是否启用过渡动画) | lv_bar_set_value(bar1, 80, LV_ANIM_ON); (带动画) |
int32_t lv_bar_get_value(lv_obj_t * obj) | 获取当前进度值 | int val = lv_bar_get_value(bar1); |
void lv_bar_set_start_value(lv_obj_t * obj, int32_t start, lv_anim_enable_t anim) | 设置进度条 “起始值”(用于显示范围区间,如 [30,70]) | lv_bar_set_start_value(bar1, 30, LV_ANIM_OFF); |
三、方向控制:水平 / 垂直切换
进度条的方向由其宽高比例决定:
- 水平进度条:宽度 > 高度(如
lv_obj_set_size(bar, 200, 20)
)。 - 垂直进度条:高度 > 宽度(如
lv_obj_set_size(bar, 20, 200)
)。
示例:创建垂直进度条
void bar_vertical_demo(void) {lv_obj_t * bar_vertical = lv_bar_create(lv_scr_act());// 设置为垂直方向(高>宽)lv_obj_set_size(bar_vertical, 20, 200);// 垂直进度条默认从下往上填充,可通过样式修改方向lv_obj_set_pos(bar_vertical, 100, 50);// 设置进度值为70(带动画)lv_obj_set_style_anim_time(bar_vertical,500,LV_STATE_DEFAULT);lv_bar_set_value(bar_vertical, 70, LV_ANIM_ON);
}
四、事件处理:监听进度变化
进度条的值变化时会触发LV_EVENT_VALUE_CHANGED
事件(如通过 API 更新或用户拖动调节时),可用于同步显示数值或执行逻辑:
// 事件回调函数:同步显示当前进度值
static void bar_event_handler(lv_event_t * e) {lv_obj_t * bar = lv_event_get_target(e);int32_t value = lv_bar_get_value(bar);// 获取用户数据(此处为显示值的标签)lv_obj_t * label = lv_event_get_user_data(e);char buf[16];sprintf(buf, "进度:%d%%", value);lv_label_set_text(label, buf);
}void bar_event_demo(void) {// 创建显示进度的标签lv_obj_t * label = lv_label_create(lv_scr_act());lv_obj_set_pos(label, 100, 150);// 创建进度条lv_obj_t * bar1 = lv_bar_create(lv_scr_act());lv_obj_set_size(bar1, 200, 20);lv_obj_set_pos(bar1, 100, 120);// 注册事件:将标签作为用户数据传递lv_obj_add_event_cb(bar1, bar_event_handler, LV_EVENT_VALUE_CHANGED, label);// 设置初始值(触发事件,更新标签)lv_bar_set_value(bar1, 30, LV_ANIM_ON);
}
五、样式定制:个性化外观
通过样式系统可定制进度条的背景、指示器颜色、圆角、边框等,核心针对LV_PART_MAIN
(背景)和LV_PART_INDICATOR
(进度指示器):
示例:定制下载进度条
lv_obj_t * bar1 = lv_bar_create(lv_scr_act());lv_obj_set_size(bar1, 250, 25);lv_obj_center(bar1); // 屏幕居中// 初始化样式static lv_style_t style_bg; // 背景样式static lv_style_t style_indic; // 指示器样式lv_style_init(&style_bg);lv_style_init(&style_indic);// 1. 背景样式:灰色圆角矩形,带边框lv_style_set_bg_color(&style_bg, lv_color_hex(0xf0f0f0)); // 背景色(浅灰)lv_style_set_border_color(&style_bg, lv_color_hex(0xcccccc)); // 边框色lv_style_set_border_width(&style_bg, 2); // 边框宽度lv_style_set_radius(&style_bg, 12); // 圆角(高度的一半,胶囊形)// 2. 指示器样式:蓝色渐变,同背景圆角lv_style_set_bg_color(&style_indic, lv_color_hex(0x0099ff)); // 指示器颜色(蓝)lv_style_set_radius(&style_indic, 10); // 略小于背景圆角,避免溢出// 应用样式到对应部分lv_obj_add_style(bar1, &style_bg, LV_PART_MAIN);lv_obj_add_style(bar1, &style_indic, LV_PART_INDICATOR);// 设置进度值(80%)lv_obj_set_style_anim_time(bar1,500,LV_STATE_DEFAULT);lv_bar_set_value(bar1, 80, LV_ANIM_ON);
六、高级特性
1. 范围进度条(显示区间)
通过lv_bar_set_start_value
和lv_bar_set_value
可显示一个数值区间(如已用空间和总空间的范围):
void bar_range_demo(void) {lv_obj_t * bar_range = lv_bar_create(lv_scr_act());lv_obj_set_size(bar_range, 200, 20);lv_obj_set_pos(bar_range, 100, 100);// 设置范围为0~100lv_bar_set_range(bar_range, 0, 100);// 显示区间 [20, 60](起始值20,当前值60)lv_obj_set_style_anim_time(bar_range,500,LV_STATE_DEFAULT);lv_bar_set_start_value(bar_range, 20, LV_ANIM_OFF); // 起始值lv_bar_set_value(bar_range, 60, LV_ANIM_ON); // 当前值(结束值)// 效果:进度条从20%到60%的部分被填充
}/* 1. 创建进度条对象 */lv_obj_t * bar = lv_bar_create(lv_scr_act()); // 在“当前活动屏幕”上创建进度条lv_obj_set_size(bar, 200, 20); // 进度条尺寸:宽200像素,高20像素lv_obj_center(bar); // 进度条在屏幕中“水平+垂直居中”/* 2. 设置进度条为「范围模式」 */lv_bar_set_mode(bar, LV_BAR_MODE_RANGE); // 开启“区间显示”模式,而非单一进度/* 3. 设置进度条的整体数值范围(可选,若需要自定义范围) */lv_bar_set_range(bar, -100, 100); // 让进度条能表示 `-100` 到 `100` 的数值/* 4. 设置「区间起始值」 */lv_bar_set_start_value(bar, -50, LV_ANIM_OFF); // 区间从 `-50` 开始,且“无动画立即生效”/* 5. 设置「区间结束值」(即进度条的“当前值”) */lv_bar_set_value(bar, 30, LV_ANIM_ON); // 区间到 `30` 结束,且“带动画平滑过渡”/* (可选)自定义进度条样式,让区间更易区分 */static lv_style_t style_indicator;lv_style_init(&style_indicator);lv_style_set_bg_color(&style_indicator, lv_color_hex(0x0099FF)); // 进度区间设为“蓝色”lv_obj_add_style(bar, &style_indicator, LV_PART_INDICATOR); // 把样式应用到「进度指示器」部分
2. 反向填充方向
通过样式的pad
属性可修改填充方向(如水平进度条从右到左,垂直从顶到底):
// 水平进度条:从右到左填充
lv_style_set_pad_left(&style_indic, 200); // 左内边距等于进度条宽度,强制从右开始
lv_style_set_pad_right(&style_indic, 0);// 垂直进度条:从顶到底填充
lv_style_set_pad_top(&style_indic, 0);
lv_style_set_pad_bottom(&style_indic, 200); // 下内边距等于进度条高度,强制从顶开始
3. 禁用交互与动画
- 禁用动画:
lv_bar_set_value(bar1, 80, LV_ANIM_OFF)
(立即更新,无过渡)。
LVGL加载器部件(spinner)
LVGL 中的加载器部件(lv_spinner
)是用于表示 “加载中” 状态的动画组件,通过旋转的图形(通常为圆弧或扇形)直观反馈任务正在进行(如数据加载、文件处理等),提升用户等待体验。其核心特点是自带旋转动画,支持自定义样式、大小和旋转速度。
一、基本结构
加载器主要由一个或多个旋转的图形元素组成,在 LVGL 中通过LV_PART_MAIN
统一控制其视觉属性(如线条颜色、宽度、旋转速度等),无需区分多个部件。
二、基本用法:创建与基本配置
1. 创建加载器
使用lv_spinner_create(parent)
创建加载器,通过lv_obj_set_size
设置大小(通常为正方形,确保旋转效果对称):
#include "lvgl.h"void spinner_basic_demo(void) {// 创建加载器,父对象为当前活动屏幕lv_obj_t * spinner1 = lv_spinner_create(lv_scr_act());// 设置大小(宽高均为50像素,正方形)lv_obj_set_size(spinner1, 50, 50);// 设置位置(屏幕中心)lv_obj_center(spinner1);
}
三、高级特性
1. 停止 / 启动旋转
加载器默认创建后自动旋转,可通过lv_anim_del
停止动画,或重新启动:
// 停止旋转(移除所有动画)
lv_anim_del(spinner1, NULL);
2. 结合标签显示状态文本
通常加载器会配合文本标签说明加载内容,示例:
void spinner_with_label_demo(void) {// 创建容器,统一管理加载器和标签lv_obj_t * container = lv_obj_create(lv_scr_act());lv_obj_set_size(container, 150, 100);lv_obj_center(container);lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN); // 垂直排列lv_obj_set_align(container, LV_ALIGN_CENTER); // 内部元素居中// 创建加载器lv_obj_t * spinner1 = lv_spinner_create(container);lv_obj_set_size(spinner1, 50, 50);// 创建标签lv_obj_t * label = lv_label_create(container);lv_label_set_text(label, "加载中...");lv_obj_set_style_pad_top(label, 10, 0); // 与加载器保持距离
}
// 创建加载器部件,父对象为当前活动屏幕(lv_scr_act()返回当前显示的屏幕)
// 返回值为创建的加载器对象指针,赋值给spinner1
lv_obj_t * spinner1 = lv_spinner_create(lv_scr_act());// 设置加载器的大小:宽100像素,高100像素(加载器通常为正方形,确保旋转动画对称)
lv_obj_set_size(spinner1, 100, 100);// 将加载器在父对象(屏幕)中居中对齐(水平和垂直方向均居中)
lv_obj_center(spinner1);// 为加载器的"主部件(LV_PART_MAIN)"设置圆弧颜色
// lv_color_hex(0x4a9f00)表示十六进制颜色值(此处为绿色)
// 作用:通常为主背景圆弧的颜色(固定不动的部分)
lv_obj_set_style_arc_color(spinner1, lv_color_hex(0x4a9f00), LV_PART_MAIN);// 为加载器的"指示器部件(LV_PART_INDICATOR)"设置圆弧颜色
// lv_color_hex(0XFF0000)表示十六进制颜色值(此处为红色)
// 作用:通常为旋转动画的圆弧颜色(动态旋转的部分,用于显示"加载中"状态)
lv_obj_set_style_arc_color(spinner1, lv_color_hex(0XFF0000), LV_PART_INDICATOR);// 为加载器的"主部件(LV_PART_MAIN)"设置圆弧宽度(线条粗细)为10像素
// 作用:控制背景圆弧的线条粗细
lv_obj_set_style_arc_width(spinner1, 10, LV_PART_MAIN);// 为加载器的"指示器部件(LV_PART_INDICATOR)"设置圆弧宽度(线条粗细)为10像素
// 作用:控制旋转动画圆弧的线条粗细(与背景圆弧保持一致时视觉更协调)
lv_obj_set_style_arc_width(spinner1, 10, LV_PART_INDICATOR);
LVGL LED部件(led)
LVGL 中的 LED 部件(lv_led
)是模拟物理 LED 指示灯的 UI 组件,主要用于直观展示设备状态(如电源开启、网络连接、错误提示等),支持颜色、亮度调节及开关状态控制,视觉上通常表现为圆形或方形的发光色块。
一、基本特性
- 核心状态:分为 “亮(开启)” 和 “灭(关闭)” 两种基本状态,支持过渡动画。
- 视觉属性:默认是圆形,可通过样式修改为方形、调整颜色、亮度和边框等。
- 用途:适合作为状态指示器(如运行状态、警告提示、功能使能标记等)。
二、基本用法:创建与状态控制
1. 创建 LED 部件
使用lv_led_create(parent)
创建 LED,通过lv_obj_set_size
设置大小(通常为正方形,确保外观对称):
#include "lvgl.h"void led_basic_demo(void) {// 创建LED,父对象为当前活动屏幕lv_obj_t * led1 = lv_led_create(lv_scr_act());// 设置大小(30x30像素,圆形外观)lv_obj_set_size(led1, 30, 30);// 设置位置(x: 50, y: 50)lv_obj_set_pos(led1, 50, 50);
}
2. 核心状态控制 API
函数原型 | 功能描述 | 示例 |
---|---|---|
void lv_led_on(lv_obj_t * obj) | 开启 LED(点亮,显示设置的颜色) | lv_led_on(led1); |
void lv_led_off(lv_obj_t * obj) | 关闭 LED(熄灭,通常显示暗灰色) | lv_led_off(led1); |
void lv_led_toggle(lv_obj_t * obj) | 切换 LED 状态(亮→灭或灭→亮) | lv_led_toggle(led1); |
void lv_led_set_brightness(lv_obj_t * obj, uint8_t brightness) | 调节亮度(0~255,值越高越亮) | lv_led_set_brightness(led1, 128); (中等亮度) |
三、样式定制:颜色与外观
LED 的样式主要通过LV_PART_MAIN
控制,可修改颜色、形状(圆形 / 方形)、边框等:
示例:定制多色 LED 指示灯
void led_style_demo(void) {// 创建红色LED(表示错误状态)lv_obj_t * led_error = lv_led_create(lv_scr_act());lv_obj_set_size(led_error, 25, 25);lv_obj_set_pos(led_error, 50, 50);lv_led_on(led_error);// 设置颜色为红色lv_obj_set_style_bg_color(led_error, lv_color_hex(0xff3333), LV_PART_MAIN);// 创建绿色LED(表示正常状态)lv_obj_t * led_ok = lv_led_create(lv_scr_act());lv_obj_set_size(led_ok, 25, 25);lv_obj_align_to(led_ok, led_error, LV_ALIGN_OUT_RIGHT_MID, 30, 0); // 右侧30像素lv_led_on(led_ok);// 设置颜色为绿色lv_obj_set_style_bg_color(led_ok, lv_color_hex(0x33cc33), LV_PART_MAIN);// 创建蓝色LED(表示待机状态),并设置为方形lv_obj_t * led_standby = lv_led_create(lv_scr_act());lv_obj_set_size(led_standby, 25, 25);lv_obj_align_to(led_standby, led_ok, LV_ALIGN_OUT_RIGHT_MID, 30, 0);lv_led_on(led_standby);// 设置颜色为蓝色+方形(圆角为0)lv_obj_set_style_bg_color(led_standby, lv_color_hex(0x3366ff), LV_PART_MAIN);lv_obj_set_style_radius(led_standby, 0, LV_PART_MAIN); // 取消圆角,变为方形
}
四、高级特性
结合动画实现呼吸效果
通过lv_anim
动画 API 控制亮度变化,实现 LED “呼吸” 效果:
// 呼吸动画回调函数(调节亮度)
static void breathe_anim_cb(lv_obj_t * obj, int32_t value) {lv_led_set_brightness(obj, value);
}// 为LED添加呼吸效果
void led_breathe_demo(void) {lv_obj_t * led = lv_led_create(lv_scr_act());lv_obj_set_size(led, 30, 30);lv_obj_center(led);lv_obj_set_style_bg_color(led, lv_color_hex(0xff9900), LV_PART_MAIN); // 橙色// 创建呼吸动画(亮度从0→255→0循环)lv_anim_t anim;lv_anim_init(&anim);lv_anim_set_var(&anim, led);lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)breathe_anim_cb);lv_anim_set_values(&anim, 0, 255); // 亮度范围lv_anim_set_time(&anim, 1000); // 一个周期(0→255)的时间(毫秒)lv_anim_set_repeat_count(&anim, LV_ANIM_REPEAT_INFINITE); // 无限循环lv_anim_set_repeat_delay(&anim, 500); // 每次循环间隔500mslv_anim_start(&anim);
}
总结
LVGL 的 LED 部件是轻量级状态指示组件,通过简单的 API 即可实现亮灭控制和亮度调节,配合样式系统可定制颜色和形状,适合各类嵌入式设备的状态显示(如电源、网络、错误提示等)。结合动画 API 还能实现呼吸、闪烁等动态效果,提升 UI 交互体验。
LVGL列表部件(list)
LVGL 中的列表部件(lv_list
)是用于展示一系列有序项目的容器组件,适合呈现菜单、选项列表、功能入口等场景。列表支持垂直滚动(当项目超出显示范围时),每个列表项可包含图标、文本等元素,且支持点击交互,是构建复杂 UI 的基础组件之一。
一、基本结构
列表部件由两个核心部分组成:
- 列表容器(
lv_list
):整体容器,负责管理所有列表项的布局和滚动行为(默认垂直排列,超出时可滚动)。 - 列表项(
lv_list_item
):列表中的单个项目,可包含图标(LV_PART_ICON
)、文本(LV_PART_MAIN
)等子元素,支持点击事件。
二、基本用法:创建列表与添加项目
1. 创建列表容器
使用lv_list_create(parent)
创建列表,通过lv_obj_set_size
设置大小(宽度通常充满父容器,高度根据内容或固定值设置):
#include "lvgl.h"void list_basic_demo(void) {// 创建列表容器,父对象为当前活动屏幕lv_obj_t * list = lv_list_create(lv_scr_act());// 设置列表大小(宽200,高300)lv_obj_set_size(list, 200, 300);// 设置列表位置(屏幕水平居中,y=50)lv_obj_set_pos(list, (LV_HOR_RES - 200)/2, 50);
}
2. 添加列表项
示例:添加多种列表项
void list_add_items_demo(void) {// 创建列表容器(本质是带滚动功能的布局容器)
lv_obj_t * list = lv_list_create(lv_scr_act());
lv_obj_set_size(list, 200, 300); // 设置列表大小:宽200px,高300px
lv_obj_center(list); // 列表在屏幕中居中对齐// 配置列表内部布局:垂直排列,项之间的垂直间距为5px
lv_obj_set_flex_flow(list, LV_FLEX_FLOW_COLUMN); // 垂直排列列表项
lv_obj_set_style_pad_row(list, 5, 0); // 列表项之间的间距// 1. 用lv_list_add_btn添加带内置图标的标准项(LVGL 8.3仍支持此函数)
// 该函数内部会自动创建按钮作为列表项,并添加图标和文本
lv_list_add_btn(list, LV_SYMBOL_HOME, "首页");
lv_list_add_btn(list, LV_SYMBOL_SETTINGS, "设置");
lv_list_add_btn(list, LV_SYMBOL_BELL, "通知");// 2. 自定义项(仅文本):用lv_btn_create替代lv_list_item_create
lv_obj_t * item = lv_btn_create(list); // 创建按钮作为列表项,父对象为列表
// 向项中添加文本标签
lv_obj_t * label = lv_label_create(item);
lv_label_set_text(label, "关于我们");
lv_obj_center(label); // 文本在按钮中居中显示// 3. 自定义项(图标+多文本):同样用按钮作为列表项
lv_obj_t * item2 = lv_btn_create(list);
lv_obj_set_flex_flow(item2, LV_FLEX_FLOW_ROW); // 项内元素水平排列
lv_obj_set_align(item2, LV_ALIGN_CENTER); // 项内元素垂直居中
lv_obj_set_style_pad_hor(item2, 10, 0); // 项的左右内边距10px// 添加图标(用标签显示内置符号)
lv_obj_t * icon = lv_label_create(item2);
lv_label_set_text(icon, LV_SYMBOL_WIFI);
lv_obj_set_style_pad_right(icon, 10, 0); // 图标右侧与文本间距10px// 添加主文本
lv_obj_t * label2 = lv_label_create(item2);
lv_label_set_text(label2, "网络状态");// 添加辅助文本(状态描述)
lv_obj_t * sub_label = lv_label_create(item2);
lv_label_set_text(sub_label, "已连接");
lv_obj_set_style_text_color(sub_label, lv_color_hex(0x00cc00), 0); // 绿色文本
lv_obj_set_style_pad_left(sub_label, 20, 0); // 与主文本间距20px(替代原align_to)
}
三、事件处理:响应列表项点击
列表项被点击时会触发LV_EVENT_CLICKED
事件,通过注册回调函数可执行对应逻辑(如页面跳转、功能触发):
#include "ptm_demo1.h"
#include "stdio.h"
#include "string.h"// 列表项点击事件回调
static void list_item_click_handler(lv_event_t * e) {lv_obj_t * item = lv_event_get_target(e); // 获取被点击的列表项// 获取项中的第一个子元素(可能是图标或文本)lv_obj_t * child = lv_obj_get_child(item, 0);// 检查子元素是否为标签if (child && lv_obj_check_type(child, &lv_label_class)) {LV_LOG_USER("点击了:%s", lv_label_get_text(child));}
}void ptm_demo(void)
{lv_obj_t * list = lv_list_create(lv_scr_act());lv_obj_set_size(list, 200, 300);lv_obj_center(list);// 添加列表项并注册事件lv_obj_t * item1 = lv_list_add_btn(list, LV_SYMBOL_HOME, "首页");lv_obj_add_event_cb(item1, list_item_click_handler, LV_EVENT_CLICKED, NULL);lv_obj_t * item2 = lv_list_add_btn(list, LV_SYMBOL_SETTINGS, "设置");lv_obj_add_event_cb(item2, list_item_click_handler, LV_EVENT_CLICKED, NULL);
}
四、样式定制:美化列表与项目
列表的样式可通过LV_PART_MAIN
(列表容器)和LV_PART_ITEM
(列表项)分别定制,包括背景色、边框、间距、选中状态等:
示例:定制深色主题列表
#include "ptm_demo1.h"
#include "stdio.h"
#include "string.h"void ptm_demo(void)
{lv_obj_t * list = lv_list_create(lv_scr_act());lv_obj_set_size(list, 220, 320);lv_obj_center(list);// 1. 列表容器样式(LV_PART_MAIN)static lv_style_t style_list;lv_style_init(&style_list);lv_style_set_bg_color(&style_list, lv_color_hex(0x222222)); // 列表背景(深灰)lv_style_set_border_width(&style_list, 0); // 无边框lv_style_set_radius(&style_list, 8); // 圆角8pxlv_obj_add_style(list, &style_list, LV_PART_MAIN);// 2. 列表项样式(默认状态)static lv_style_t style_item;lv_style_init(&style_item);lv_style_set_bg_color(&style_item, lv_color_hex(0x333333)); // 项背景(中灰)lv_style_set_pad_hor(&style_item, 15); // 水平内边距15pxlv_style_set_pad_ver(&style_item, 12); // 垂直内边距12pxlv_style_set_radius(&style_item, 4); // 项圆角4pxlv_obj_add_style(list, &style_item, LV_PART_ITEMS);// 3. 列表项选中/点击状态样式static lv_style_t style_item_clicked;lv_style_init(&style_item_clicked);lv_style_set_bg_color(&style_item_clicked, lv_color_hex(0x444444)); // 点击时背景(浅灰)lv_obj_add_style(list, &style_item_clicked, LV_PART_ITEMS | LV_STATE_CHECKED);// 4. 文本样式static lv_style_t style_text;lv_style_init(&style_text);lv_style_set_text_color(&style_text, lv_color_hex(0xffffff)); // 文本白色lv_style_set_text_font(&style_text, &lv_font_montserrat_14); // 字体大小14lv_obj_add_style(list, &style_text, LV_PART_ITEMS | LV_PART_MAIN); // 应用到项的文本// 添加列表项lv_list_add_btn(list, LV_SYMBOL_HOME, "首页");lv_list_add_btn(list, LV_SYMBOL_SETTINGS, "设置");lv_list_add_btn(list, LV_SYMBOL_BELL, "通知");
}
五、高级特性
列表滚动控制
列表默认支持垂直滚动,可通过以下 API 控制滚动行为:
// 滚动到列表顶部
lv_obj_scroll_to_y(list, 0, LV_ANIM_ON); // 带动画滚动到y=0位置// 滚动到指定项(确保项可见)
lv_obj_scroll_to_view(item, LV_ANIM_ON); // 带动画滚动到item可见
总结
LVGL 列表部件(lv_list
)通过简洁的 API 实现了有序项目展示,支持滚动、点击交互和高度定制的样式,适合构建菜单、选项列表等场景。通过lv_list_add_btn
可快速创建标准项,或用lv_list_item_create
实现复杂布局,配合事件处理可实现丰富的交互逻辑,是嵌入式 GUI 中组织多选项内容的核心组件。
LVGL下拉列表部件(dropdown)
LVGL(Light and Versatile Graphics Library)中的下拉列表部件(dropdown)是一种常用的交互组件,适用于在有限空间内展示多个选项,用户点击后会展开列表供选择,选择后自动收起,非常适合设置项、选项筛选等场景。
下拉列表基本特性
- 默认包含一个触发按钮(显示当前选中项或提示文本)和一个可展开的选项列表
- 支持通过字符串列表设置选项(使用
\n
分隔选项) - 可自定义展开 / 收起动画、列表高度、样式等
- 支持事件监听(如选项变更、展开 / 收起等)
核心 API 与用法
以下是下拉列表的常用操作函数和基础示例:
1. 创建下拉列表
使用lv_dropdown_create(parent)
创建下拉列表,参数为父对象(如屏幕、容器等)。
// 创建下拉列表,父对象为当前屏幕
lv_obj_t * dropdown = lv_dropdown_create(lv_scr_act());
2. 设置选项
通过lv_dropdown_set_options(dropdown, options)
设置选项,options
是用\n
分隔的字符串(如 "Option 1\nOption 2\nOption 3")。
// 设置下拉列表选项
lv_dropdown_set_options(dropdown, "Red\nGreen\nBlue\nYellow");//添加列表选项
lv_dropdown_add_option(dropdown,"e",2);
3. 设置 / 获取选中项
lv_dropdown_set_selected(dropdown, idx)
:设置默认选中项(idx
为选项索引,从 0 开始)lv_dropdown_get_selected(dropdown)
:获取当前选中项的索引
// 默认选中第2项(索引1,对应"Green")
lv_dropdown_set_selected(dropdown, 1, 0);// 获取当前选中项索引
uint32_t selected_idx = lv_dropdown_get_selected(dropdown);
LVGL滚轮部件(roller)
LVGL 中的滚轮部件(roller)是一种通过滑动交互选择选项的组件,通常显示多个选项,中间的选项为当前选中状态,适合需要快速滚动选择的场景(如时间选择、数值调整、列表筛选等)。其交互方式直观,占用空间固定,是移动设备和嵌入式界面中常用的交互元素。
滚轮部件核心特性
- 固定显示一定数量的选项(通常为奇数),中间项自动高亮为选中状态
- 支持上下滑动切换选项,滑动时会有惯性动画效果
- 可配置是否允许循环滚动(选项滚动到末尾后自动回到开头)
- 支持自定义可见选项数量、选项高度、样式(如选中项高亮)
- 提供选项变更事件,便于监听用户选择
核心 API 与用法
以下是滚轮部件的常用操作函数及基础用法:
1. 创建滚轮
使用lv_roller_create(parent)
创建滚轮,参数为父对象(如屏幕、容器等)。
// 在当前屏幕创建滚轮
lv_obj_t * roller = lv_roller_create(lv_scr_act());
2. 设置选项
通过lv_roller_set_options(roller, options, mode)
设置选项,其中:
options
:用\n
分隔的选项字符串(如 "1\n2\n3\n4")mode
:选项模式,常用LV_ROLLER_MODE_INFINITE
(循环滚动)或LV_ROLLER_MODE_NORMAL
(非循环)
// 设置选项为星期,允许循环滚动
lv_roller_set_options(roller, "Sunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday", LV_ROLLER_MODE_INFINITE);
3. 配置可见选项数量
通过lv_roller_set_visible_row_count(roller, count)
设置可见选项行数(通常设为奇数,方便中间项作为选中项)。
// 设置可见行数为5行(中间行为选中项)
lv_roller_set_visible_row_count(roller, 5);
4. 设置 / 获取选中项
lv_roller_set_selected(roller, idx, anim_en)
:设置选中项(idx
为索引,anim_en
为true
时启用滚动动画)lv_roller_get_selected_idx(roller)
:获取当前选中项的索引lv_roller_get_selected_str(roller, buf, buf_size)
:获取当前选中项的文本(需传入缓冲区)
// 默认选中第2项(索引1,对应"Monday"),启用动画
lv_roller_set_selected(roller, 1, true);// 获取选中项文本
char buf[32];
lv_roller_get_selected_str(roller, buf, sizeof(buf));
LV_LOG_USER("Selected: %s", buf);
// 1. 创建滚轮,父对象为当前屏幕lv_obj_t * roller = lv_roller_create(lv_scr_act());// 2. 设置选项(12个月份),启用循环滚动lv_roller_set_options(roller, "January\nFebruary\nMarch\nApril\nMay\nJune\n""July\nAugust\nSeptember\nOctober\nNovember\nDecember", LV_ROLLER_MODE_INFINITE);// 3. 设置可见行数为5行(中间行为选中项)lv_roller_set_visible_row_count(roller, 5);// 4. 默认选中第6项(索引5,对应"June"),带滚动动画lv_roller_set_selected(roller, 5, true);// 5. 调整位置(屏幕居中)lv_obj_align(roller, LV_ALIGN_CENTER, 0, 0);// 设置选项间隔
lv_obj_set_style_text_line_space(roller,30,LV_STATE_DEFAULT);
LVGL滑块部件(slider)
LVGL(Light and Versatile Graphics Library)中的滑块部件(slider)是一个常用的交互元素,允许用户通过拖动来选择一个范围内的值。以下是关于 LVGL 滑块部件的详细介绍和使用方法:
滑块部件的基本特性
- 支持水平和垂直方向
- 可设置最小值和最大值
- 支持步长设置(每次拖动的最小变化量)
- 可以显示当前值
- 支持自定义样式(颜色、大小、形状等)
- 具有多种事件(值变化、按下、释放等)
基本用法示例
下面是创建和使用滑块部件的基本代码示例:
// 创建一个滑块对象lv_obj_t * slider = lv_slider_create(lv_scr_act());// 设置滑块位置和大小lv_obj_set_size(slider, 200, 20); // 宽度200,高度20lv_obj_center(slider); // 居中显示// 设置滑块范围和初始值lv_slider_set_range(slider, 0, 100); // 范围0-100lv_slider_set_value(slider, 50, LV_ANIM_ON); // 初始值50,启用动画
常用 API 函数
-
创建滑块
lv_obj_t * lv_slider_create(lv_obj_t * parent);
-
设置 / 获取值
void lv_slider_set_value(lv_obj_t * slider, int32_t value, lv_anim_enable_t anim); int32_t lv_slider_get_value(lv_obj_t * slider);
-
设置范围
void lv_slider_set_range(lv_obj_t * slider, int32_t min, int32_t max);
-
设置步长
void lv_slider_set_step(lv_obj_t * slider, uint32_t step);
-
设置方向
void lv_slider_set_mode(lv_obj_t * slider, lv_slider_mode_t mode); // 模式可以是LV_SLIDER_MODE_HORIZONTAL或LV_SLIDER_MODE_VERTICAL
样式设置
可以通过样式自定义滑块的外观:
// 创建样式
static lv_style_t style_indic;
static lv_style_t style_knob;// 初始化样式
lv_style_init(&style_indic);
lv_style_set_bg_color(&style_indic, lv_color_hex(0x0099FF)); // 指示器颜色
lv_style_set_radius(&style_indic, LV_RADIUS_CIRCLE); // 圆形指示器lv_style_init(&style_knob);
lv_style_set_bg_color(&style_knob, lv_color_hex(0x0066CC)); // 旋钮颜色
lv_style_set_radius(&style_knob, LV_RADIUS_CIRCLE); // 圆形旋钮
lv_style_set_size(&style_knob, 24, 24); // 旋钮大小// 应用样式到滑块
lv_obj_add_style(slider, &style_indic, LV_PART_INDICATOR);
lv_obj_add_style(slider, &style_knob, LV_PART_KNOB);lv_slider_set_mode(slider,LV_SLIDER_MODE_RANGE);//滑块模式
lv_slider_set_left_value(slider,20,LV_ANIM_OFF);//设置左值
lv_slider_get_left_value(slider);//获取左值
滑块部件在音频音量控制、亮度调节、进度设置等场景中非常有用,通过灵活的样式设置和事件处理,可以满足各种 UI 设计需求。
LVGL圆弧部件(arc)
LVGL 中的圆弧部件(arc)是一种灵活的图形元素,常用于实现仪表盘、进度环、旋钮控制器等交互组件。它支持自定义角度范围、样式和交互方式,非常适合需要直观展示或调节数值的场景。
圆弧部件的核心特性
- 可自定义起始角度和结束角度(0° 为右侧水平方向,顺时针递增)
- 支持设置数值范围(最小值和最大值)
- 可作为输入设备(通过拖动旋钮改变值)或纯显示组件
- 包含多个可独立样式化的部分:背景弧、前景弧(进度)、旋钮
- 支持动画过渡效果
- 可设置是否闭环(首尾相连)
基本用法示例
// 事件回调函数
void arc_event(lv_event_t *e)
{// 获取事件源(圆弧对象)lv_obj_t *arc = lv_event_get_target(e);// 获取用户数据(标签对象)lv_obj_t *label = lv_event_get_user_data(e);// 确保只处理值变化事件if(lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {// 获取圆弧当前值int32_t value = lv_arc_get_value(arc);// 转换为字符串并更新标签char buf[16];lv_snprintf(buf, sizeof(buf), "%d", value);lv_label_set_text(label, buf);}
}void ptm_demo(void)
{// 创建圆弧对象lv_obj_t *arc = lv_arc_create(lv_scr_act());lv_obj_center(arc);lv_arc_set_range(arc, -100, 200); // 设置范围-100到200lv_arc_set_value(arc, 80); // 初始值80// 创建标签(作为圆弧的子对象)lv_obj_t *label = lv_label_create(arc);lv_obj_center(label); // 标签在圆弧中心显示// 初始化标签显示char buf[16];lv_snprintf(buf, sizeof(buf), "%d", lv_arc_get_value(arc));lv_label_set_text(label, buf);// 添加事件回调,将标签作为用户数据传递lv_obj_add_event_cb(arc, arc_event, LV_EVENT_VALUE_CHANGED, label);
}
// 设置圆弧的数值范围:最小值为0,最大值为200
// 后续通过lv_arc_set_value()设置的值将被限制在0~200之间
lv_arc_set_range(arc, 0, 200);// 设置背景弧(BG)的角度范围:起始角度160°,结束角度90°
// 角度定义:0°为右侧水平方向,顺时针递增(90°向下,180°向左,270°向上)
// 此处160°到90°表示一个逆时针的弧形(因160 > 90),视觉上是一段"凹陷"的圆弧
lv_arc_set_bg_angles(arc, 160, 90);// 设置指示弧(INDIC,显示当前值的部分)的初始角度范围:起始角度160°,结束角度90°
// 初始状态下指示弧与背景弧完全重合(通常表示初始值为最小值0)
// 当通过lv_arc_set_value()或用户交互改变值时,指示弧的结束角度会动态变化
lv_arc_set_angles(arc, 160, 90);// 设置整个圆弧的旋转角度:180°
// 旋转会让圆弧整体绕中心顺时针旋转180°(原0°方向从右侧水平变为左侧水平)
// 常用于调整圆弧的初始朝向,使其符合UI设计的方位需求
lv_arc_set_rotation(arc, 180);// 设置圆弧的工作模式为"反向模式"(LV_ARC_MODE_REVERSE)
// 默认模式下,值增大时指示弧顺时针扩展;反向模式下,值增大时指示弧逆时针扩展
// 配合角度范围使用,可灵活控制值与角度的映射方向
lv_arc_set_mode(arc, LV_ARC_MODE_REVERSE);// 设置旋钮(KNOB)拖动时的角度变化率:90°/s
// 该值限制了旋钮拖动的最大速度(单位:角度/秒),数值越小调节越精细
// 影响交互灵敏度,适用于需要精确调节的场景
lv_arc_set_change_rate(arc, 90);
典型应用场景
- 音量 / 亮度调节旋钮
- 进度指示器(如加载进度、完成百分比)
- 仪表盘(如速度表、温度计)
- 角度 / 比例可视化组件
通过灵活组合角度范围、样式和事件处理,圆弧部件可以满足从简单进度显示到复杂交互控件的多种需求。
LVGL线条部件(line)
LVGL 中的线条部件(line)是用于绘制直线或折线的轻量级图形组件,可用于实现图表、连接线、分隔线、简单图形等场景。它支持自定义线条样式、点集配置和交互属性,使用灵活。
核心特性
- 支持绘制单条直线或多条折线(通过点集定义)
- 可自定义线宽、颜色、透明度
- 支持虚线样式(设置线段长度和间隔)
- 可设置端点样式(圆角或方角)
- 可作为独立部件或其他组件的子对象
基本用法示例
以下是创建线条部件的基础代码,包括定义点集、设置样式和基本属性:
#include "lvgl.h"void line_demo(void) {// 1. 定义线条的点集(坐标基于父对象的坐标系)static lv_point_precise_t points[] = {{50, 50}, // 第一个点 (x=50, y=50){150, 50}, // 第二个点 (x=150, y=50):水平向右{150, 150}, // 第三个点 (x=150, y=150):垂直向下{50, 150}, // 第四个点 (x=50, y=150):水平向左{50, 50} // 第五个点:回到起点(形成矩形)};// 2. 创建线条对象lv_obj_t * line = lv_line_create(lv_scr_act());// 3. 设置线条的点集(参数:线条对象、点数组、点数量)lv_line_set_points(line, points, sizeof(points)/sizeof(lv_point_t));// 4. 设置线条位置(可选,默认在父对象左上角)lv_obj_set_pos(line, 20, 20); // 距离父对象左20px,上20px// 5. (可选)设置线条样式static lv_style_t style_line;lv_style_init(&style_line);lv_style_set_line_color(&style_line, lv_color_hex(0x0099FF)); // 蓝色线条lv_style_set_line_width(&style_line, 3); // 线宽3pxlv_style_set_line_rounded(&style_line, true); // 线条拐角圆角lv_obj_add_style(line, &style_line, LV_PART_MAIN); // 应用样式}
static lv_style_t style_thick;
lv_style_init(&style_thick);
lv_style_set_line_color(&style_thick, lv_color_hex(0xAA00FF)); // 紫色
lv_style_set_line_width(&style_thick, 8); // 粗线8px
lv_style_set_line_opa(&style_thick, 128); // 半透明(255的一半)
lv_style_set_line_rounded(&style_thick, true); // 圆角拐角
lv_obj_add_style(line, LV_LINE_PART_MAIN, &style_thick);
典型应用场景
- 数据可视化:绘制折线图展示趋势数据
- 界面装饰:作为分隔线、边框或背景图案
- 连接线:在 UI 元素间绘制关联线(如流程图、思维导图)
- 简单图形:通过点集组合绘制矩形、三角形等基础图形
注意事项
- 点的坐标是相对父对象的局部坐标,而非屏幕全局坐标
- 线条默认没有交互事件,若需要点击检测,可添加事件回调并结合
lv_obj_hit_test()
判断 - 复杂图形建议使用
lv_canvas
(画布)部件,线条更适合简单场景
通过灵活配置点集和样式,线条部件可以满足从简单装饰到基础图形绘制的多种需求,是 LVGL 中轻量级图形绘制的重要组件。
LVGL图片部件(img)
LVGL 的图片部件(img)是用于显示图像的核心组件,支持多种图片格式、动态控制和样式自定义,广泛用于显示图标、背景、自定义 UI 元素等场景。以下是其详细用法和特性:
核心特性
- 支持多种图片格式:LVGL 内置格式(如
LV_IMG_FORMAT_ARGB8888
、LV_IMG_FORMAT_INDEXED
等)、符号字体(LV_SYMBOL_*
)、外部格式(需配合解码库支持 JPG/PNG 等)。 - 支持缩放、旋转、偏移等几何变换。
- 可设置透明度、混合模式(如叠加、反转)。
- 支持图片切片(仅显示部分区域)。
- 可作为其他部件的子对象(如按钮图标、列表项图标)。
图片源(src)类型
图片部件的核心是src
(图片源),LVGL 支持 3 种类型的src
:
-
符号图片:使用 LVGL 内置的符号字体(本质是特殊字符),如
LV_SYMBOL_OK
(√)、LV_SYMBOL_SETTINGS
(⚙️)。优势:占用内存小,可通过字体样式修改颜色 / 大小。 -
图片数组:将图片数据转换为 C 数组(通过 LVGL 图片转换器生成),存储在程序内存中。优势:无需文件系统,适合嵌入式系统。
-
文件系统图片:从文件系统(如 SD 卡、SPIFFS)加载图片文件(需配置 LVGL 支持文件系统)。
基本用法示例
1. 显示符号图片
void img_symbol_demo(void) {// 创建图片对象lv_obj_t * img = lv_img_create(lv_scr_act());// 设置符号图片源(使用内置符号)lv_img_set_src(img, LV_SYMBOL_OK);// 设置大小(符号本质是字体,通过尺寸调整大小)lv_obj_set_style_text_font(img, &lv_font_montserrat_24, 0);// 设置颜色(符号颜色通过文本颜色控制)lv_obj_set_style_text_color(img, lv_color_hex(0x00CC00), 0); // 绿色// 居中显示lv_obj_center(img);
}
2. 显示数组图片(最常用)
步骤:① 使用LVGL 图片转换器将图片转为 C 数组(选择合适格式,如CF_TRUE_COLOR_ALPHA
)。② 生成的数组会包含图片宽、高、格式等信息,例如:
// 转换后生成的图片数组(示例)
const lv_img_dsc_t img_logo = {.header.always_zero = 0,.header.w = 100, // 宽度.header.h = 50, // 高度.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA, // 格式(带透明度).data_size = 100*50*4, // 数据大小(像素×每个像素字节数).data = img_logo_data // 像素数据(自动生成)
};
③ 在代码中使用:
void img_array_demo(void) {// 创建图片对象lv_obj_t * img = lv_img_create(lv_scr_act());// 设置数组图片源lv_img_set_src(img, &img_logo);// 位置调整(距离左上角x=20, y=20)lv_obj_set_pos(img, 20, 20);
}// 设置图片X轴方向的偏移量(单位:像素)
// 作用:控制图片显示的水平起始位置,仅显示从X=100处开始的部分(左侧100px将被裁剪)
// 例如:原图宽200px,设置offset_x=100后,仅显示右侧100px区域
lv_img_set_offset_x(img, 100);// 设置图片Y轴方向的偏移量(单位:像素)
// 作用:控制图片显示的垂直起始位置,仅显示从Y=208处开始的部分(顶部208px将被裁剪)
lv_img_set_offset_y(img, 208);// 设置图片的颜色重映射(替换非透明区域的颜色)
// 参数说明:
// - img:目标图片对象
// - lv_color_hex(0xff00ff):重映射的目标颜色(这里是洋红色)
// - LV_PART_MAIN:应用样式的部件部分(图片的主要区域)
// 效果:图片中所有非透明的像素将被替换为洋红色
lv_obj_set_style_img_recolor(img, lv_color_hex(0xff00ff), LV_PART_MAIN);// 设置颜色重映射的透明度(0~255)
// 参数150表示:重映射颜色的透明度为150(约58%不透明)
// 效果:洋红色会以半透明状态叠加在原图上,值越小越接近原图颜色
lv_obj_set_style_img_recolor_opa(img, 150, LV_PART_MAIN);// 设置图片的缩放比例
// LVGL中缩放基准为256(代表1倍原尺寸),512表示2倍缩放(放大到原来的2倍)
// 其他常见值:128=0.5倍(缩小),384=1.5倍
lv_img_set_zoom(img, 512);// 设置图片的旋转角度(单位:度,顺时针为正方向)
// 这里设置为90度,表示图片顺时针旋转90度
// 注意:需开启LVGL配置中的LV_USE_IMG_ROTATE才能生效
lv_img_set_angle(img, 900);// 强制更新图片的布局
// 作用:让之前的设置(如旋转、缩放、偏移)立即生效,无需等待下一次UI刷新
// 常用于动态修改属性后需要立即显示效果的场景
lv_obj_update_layout(img);// (注:函数名应为lv_img_set_pivot,原代码可能笔误)设置旋转的支点(中心点)
// 参数(0,0)表示以图片的左上角为旋转中心(默认支点为图片中心)
// 支点坐标是相对于图片自身的局部坐标(0,0为左上角,图片宽高为右下角)
lv_img_set_pivot(img, 0, 0);
3. 显示文件系统图片(需配置文件系统)
void img_file_demo(void) {// 确保LVGL已配置文件系统(如lv_fs_fatfs、lv_fs_spiffs等)lv_obj_t * img = lv_img_create(lv_scr_act());// 设置文件路径(根据实际文件系统调整前缀,如"SD:/logo.png")lv_img_set_src(img, "S:/images/bg.jpg");// 居中显示lv_obj_center(img);
}
常用 API 函数
功能 | API 函数 | 说明 |
---|---|---|
设置图片源 | void lv_img_set_src(lv_obj_t * img, const void * src) | src 可为符号字符串(如LV_SYMBOL_OK )、图片数组指针(如&img_logo )、文件路径(如"S:/img.png" )。 |
获取图片源 | const void * lv_img_get_src(lv_obj_t * img) | 返回当前图片源。 |
调整大小 | void lv_obj_set_size(lv_obj_t * img, lv_coord_t w, lv_coord_t h) | 强制设置图片显示尺寸(可能拉伸)。 |
按比例缩放 | void lv_img_set_zoom(img, uint16_t zoom) | zoom=256 为原尺寸,512 为 2 倍放大,128 为 0.5 倍缩小。 |
旋转 | void lv_img_set_angle(img, int16_t angle) | 旋转角度(0~360 度),需启用LV_USE_IMG_ROTATE 配置。 |
设置透明度 | lv_style_set_img_opa(style, uint8_t opa) | 0(完全透明)~255(不透明),通过样式设置。 |
显示部分区域 | void lv_img_set_offset_x/y(img, lv_coord_t ofs_x/ofs_y) | 偏移显示区域(仅显示图片的一部分)。 |
样式自定义
图片部件的样式通过lv_obj_add_style()
设置,常用样式属性:
样式属性 | 说明 | 示例代码 |
---|---|---|
img_opa | 整体透明度(0~255) | lv_style_set_img_opa(&style, 128); (半透明) |
img_recolor | 颜色重映射(替换图片非透明区域颜色) | lv_style_set_img_recolor(&style, lv_color_hex(0xFF0000)); (转为红色) |
img_recolor_opa | 颜色重映射的透明度(0~255) | lv_style_set_img_recolor_opa(&style, 100); |
img_mode | 混合模式(如LV_BLEND_MODE_ADD 叠加) | lv_style_set_img_mode(&style, LV_BLEND_MODE_SUBTRACT); |
样式示例(红色半透明图片):
void img_style_demo(void) {lv_obj_t * img = lv_img_create(lv_scr_act());lv_img_set_src(img, &img_logo);static lv_style_t style_img;lv_style_init(&style_img);// 重映射为红色lv_style_set_img_recolor(&style_img, lv_color_hex(0xFF0000));// 重映射透明度50%lv_style_set_img_recolor_opa(&style_img, 128);// 整体半透明lv_style_set_img_opa(&style_img, 128);lv_obj_add_style(img, LV_IMG_PART_MAIN, &style_img);
}
交互与高级用法
1. 图片点击事件
static void img_click_cb(lv_event_t * e) {LV_LOG_USER("图片被点击了!");
}void img_click_demo(void) {lv_obj_t * img = lv_img_create(lv_scr_act());lv_img_set_src(img, LV_SYMBOL_SETTINGS);lv_obj_set_style_text_font(img, &lv_font_montserrat_48, 0);// 添加点击事件lv_obj_add_event_cb(img, img_click_cb, LV_EVENT_CLICKED, NULL);// 允许接收点击事件(默认允许)lv_obj_set_clickable(img, true);
}
2. 动态切换图片
// 定义两个图片源
const char * img_srcs[] = {LV_SYMBOL_PLAY, LV_SYMBOL_PAUSE};
uint8_t img_idx = 0;static void toggle_img_cb(lv_event_t * e) {lv_obj_t * img = lv_event_get_target(e);img_idx = (img_idx + 1) % 2;lv_img_set_src(img, img_srcs[img_idx]); // 切换图片源
}void img_toggle_demo(void) {lv_obj_t * img = lv_img_create(lv_scr_act());lv_img_set_src(img, img_srcs[0]);lv_obj_add_event_cb(img, toggle_img_cb, LV_EVENT_CLICKED, NULL);
}
注意事项
- 图片格式选择:嵌入式系统优先使用
LV_IMG_CF_INDEXED
(索引色)或LV_IMG_CF_ALPHA_1BIT
(仅透明 / 不透明),减少内存占用。 - 图片转换:使用 LVGL 官方图片转换器,选择 “True color with alpha”(带透明度)或 “Indexed”(索引色)格式,生成 C 数组。
- 内存优化:大图片建议使用 “切片”(
lv_img_set_offset_*
)或动态加载,避免占用过多 RAM。 - 硬件加速:若平台支持 GPU,可开启
LV_USE_GPU
配置,提升图片渲染性能。
应用场景
- 显示图标(如按钮、工具栏图标)
- 绘制背景图片
- 实现自定义控件(如仪表盘刻度、进度条图案)
- 显示动态内容(如实时摄像头画面,需配合数据刷新)
通过灵活的图片源选择和样式控制,图片部件可以满足从简单图标到复杂图像显示的各种需求。
LVGL色环部件(colorwheel)
LVGL 的色环部件(colorwheel)是用于可视化选择颜色的交互组件,核心功能是让用户通过拖动、点击等操作直观地调整色相(Hue)、饱和度(Saturation)和亮度(Value/Lightness),最终输出 RGB 或 HSV 格式的颜色值。它广泛用于调色板、主题设置、绘图工具等场景。
一、核心特性
- 支持 HSV(色相 - 饱和度 - 亮度) 和 RGB(红 - 绿 - 蓝) 两种颜色模型切换;
- 包含三大交互区域:
- 色相环(Hue Ring):环形区域,拖动选择色相(0°~360°,对应红、橙、黄、绿、蓝、紫等);
- 饱和度 / 亮度面板(Saturation-Value Panel):中心矩形区域,拖动调节当前色相的饱和度和亮度;
- 颜色预览块(Color Preview):显示当前选中的颜色(部分版本需自定义,或通过事件回调联动);
- 支持自定义尺寸、样式(色相环宽度、面板颜色、选择器样式等);
- 颜色变化时触发
LV_EVENT_VALUE_CHANGED
事件,方便联动其他部件(如实时更新背景色、文本色)。
二、基本用法示例
以下是创建色环并联动标签显示颜色的完整代码,包含初始化、事件回调和颜色应用:
#include "lvgl.h"// 事件回调:色环颜色变化时触发
static void colorwheel_event_cb(lv_event_t *e) {// 1. 获取色环对象和当前选中的颜色(RGB格式)lv_obj_t *colorwheel = lv_event_get_target(e);lv_color32_t selected_color = lv_colorwheel_get_rgb(colorwheel); // 获取RGB颜色// 2. 获取联动的标签对象(通过用户数据传递)lv_obj_t *label = lv_event_get_user_data(e);// 3. 应用颜色到标签(文字色+背景色)lv_obj_set_style_text_color(label, selected_color, LV_PART_MAIN); // 文字色lv_obj_set_style_bg_color(label, selected_color, LV_PART_MAIN); // 背景色lv_obj_set_style_bg_opa(label, 255, LV_PART_MAIN); // 背景不透明// 4. (可选)在标签上显示颜色的RGB值char color_str[32];lv_snprintf(color_str, sizeof(color_str), "RGB: %02X, %02X, %02X", selected_color.red, selected_color.green, selected_color.blue);lv_label_set_text(label, color_str);
}void colorwheel_demo(void) {// 1. 创建色环对象(父对象为当前屏幕)lv_obj_t *colorwheel = lv_colorwheel_create(lv_scr_act());// 2. 设置色环尺寸(宽=高,色环为圆形)lv_obj_set_size(colorwheel, 200, 200); // 直径200px// 3. 设置初始颜色(示例:红色,RGB(255,0,0))lv_color32_t init_color = lv_color_hex(0xFF0000);lv_colorwheel_set_rgb(colorwheel, init_color);// 4. (可选)设置颜色模型(默认HSV,可改为RGB)// lv_colorwheel_set_mode(colorwheel, LV_COLORWHEEL_MODE_RGB);// 5. 创建联动的标签(用于显示颜色信息和预览)lv_obj_t *color_label = lv_label_create(lv_scr_act());lv_obj_set_pos(color_label, 230, 80); // 标签位于色环右侧lv_obj_set_style_text_font(color_label, &lv_font_montserrat_16, 0); // 字体大小// 6. 添加颜色变化事件,将标签作为用户数据传递lv_obj_add_event_cb(colorwheel, colorwheel_event_cb, LV_EVENT_VALUE_CHANGED, color_label);// 7. 初始化标签显示(初始颜色信息)char init_str[32];lv_snprintf(init_str, sizeof(init_str), "RGB: %02X, %02X, %02X", init_color.red, init_color.green, init_color.blue);lv_label_set_text(color_label, init_str);lv_obj_set_style_text_color(color_label, init_color, LV_PART_MAIN);lv_obj_set_style_bg_color(color_label, init_color, LV_PART_MAIN);lv_obj_set_style_bg_opa(color_label, 255, LV_PART_MAIN);
}
三、常用 API 函数
色环的核心 API 围绕 “颜色获取 / 设置”“模式切换”“外观配置” 展开,以下是关键函数说明:
功能分类 | API 函数 | 说明 |
---|---|---|
颜色操作 | lv_color32_t lv_colorwheel_get_rgb(lv_obj_t *cw) | 获取当前选中的颜色(RGB 格式,lv_color32_t 包含 red/green/blue/alpha 通道)。 |
void lv_colorwheel_set_rgb(lv_obj_t *cw, lv_color32_t color) | 设置色环的初始 / 目标颜色(RGB 格式)。 | |
lv_hsv_t lv_colorwheel_get_hsv(lv_obj_t *cw) | 获取当前选中的颜色(HSV 格式,lv_hsv_t 包含 hue (0-360)/sat (0-100)/val (0-100))。 | |
void lv_colorwheel_set_hsv(lv_obj_t *cw, lv_hsv_t hsv) | 设置色环的初始 / 目标颜色(HSV 格式)。 | |
模式切换 | void lv_colorwheel_set_mode(lv_obj_t *cw, lv_colorwheel_mode_t mode) | 设置颜色模型:- LV_COLORWHEEL_MODE_HSV (默认,色相环 + 饱和度 / 亮度面板);- LV_COLORWHEEL_MODE_RGB (RGB 三通道滑块,无环)。 |
外观配置 | void lv_colorwheel_set_ring_width(lv_obj_t *cw, lv_coord_t width) | 设置色相环的宽度(单位:像素,默认约 20px)。 |
void lv_colorwheel_set_panel_size(lv_obj_t *cw, lv_coord_t size) | 设置中心饱和度 / 亮度面板的尺寸(单位:像素,默认约色环直径的 1/3)。 | |
状态获取 | lv_colorwheel_mode_t lv_colorwheel_get_mode(lv_obj_t *cw) | 获取当前颜色模型。 |
四、样式自定义
色环包含多个可独立样式化的 “部件部分(part)”,通过lv_obj_add_style()
设置样式,常用part
和样式属性如下:
部件部分(Part) | 说明 | 常用样式属性(lv_style_set_* ) |
---|---|---|
LV_COLORWHEEL_PART_RING | 色相环本身 | bg_color (环的底色,默认透明)、border_color (环的边框色)、border_width (边框宽度)。 |
LV_COLORWHEEL_PART_CTRL | 色相环的选择器(小圆圈) | bg_color (选择器颜色,默认白色)、border_color (选择器边框色)、size (选择器大小)。 |
LV_COLORWHEEL_PART_PANEL | 中心饱和度 / 亮度面板 | bg_color (面板底色)、border_color (面板边框色)、border_width (面板边框宽度)。 |
LV_COLORWHEEL_PART_INDIC | 面板的选择器(小方块) | bg_color (选择器颜色,默认白色)、border_color (选择器边框色)、size (选择器大小)。 |
样式自定义示例(深色主题色环)
void colorwheel_styled_demo(void) {lv_obj_t *colorwheel = lv_colorwheel_create(lv_scr_act());lv_obj_set_size(colorwheel, 200, 200);// 1. 初始化样式static lv_style_t style_ring, style_ctrl, style_panel, style_indic;lv_style_init(&style_ring);lv_style_init(&style_ctrl);lv_style_init(&style_panel);lv_style_init(&style_indic);// 2. 色相环样式(深色边框)lv_style_set_border_color(&style_ring, lv_color_hex(0x333333)); // 边框深灰lv_style_set_border_width(&style_ring, 2); // 边框宽2px// 3. 色相环选择器样式(白色+深灰边框)lv_style_set_bg_color(&style_ctrl, lv_color_white()); // 选择器白色lv_style_set_border_color(&style_ctrl, lv_color_hex(0x333333));// 边框深灰lv_style_set_border_width(&style_ctrl, 2); // 边框宽2pxlv_style_set_size(&style_ctrl, 12, 12); // 选择器大小12px// 4. 中心面板样式(深灰边框)lv_style_set_border_color(&style_panel, lv_color_hex(0x333333));// 边框深灰lv_style_set_border_width(&style_panel, 2); // 边框宽2px// 5. 面板选择器样式(黑色+白色边框)lv_style_set_bg_color(&style_indic, lv_color_black()); // 选择器黑色lv_style_set_border_color(&style_indic, lv_color_white()); // 边框白色lv_style_set_border_width(&style_indic, 2); // 边框宽2pxlv_style_set_size(&style_indic, 10, 10); // 选择器大小10px// 6. 应用样式到色环lv_obj_add_style(colorwheel, LV_COLORWHEEL_PART_RING, &style_ring);lv_obj_add_style(colorwheel, LV_COLORWHEEL_PART_CTRL, &style_ctrl);lv_obj_add_style(colorwheel, LV_COLORWHEEL_PART_PANEL, &style_panel);lv_obj_add_style(colorwheel, LV_COLORWHEEL_PART_INDIC, &style_indic);
}
五、典型应用场景
- UI 主题配置:让用户自定义界面的主色调、文本色、背景色;
- 绘图工具:作为画笔颜色选择器,配合画布(
lv_canvas
)使用; - 设备个性化:如智能灯色温调节、显示屏背光颜色设置;
- 数据可视化:自定义图表(
lv_chart
)的线条 / 填充色。
六、注意事项
- 配置依赖:使用前需确保 LVGL 配置中开启了
LV_USE_COLORWHEEL
(默认开启,若关闭需在lv_conf.h
中设置#define LV_USE_COLORWHEEL 1
); - 尺寸适配:色环建议设置为正方形(宽 = 高),否则色相环会拉伸变形;
- 颜色格式:
lv_color32_t
支持 Alpha 通道(透明度),但色环默认不调节透明度,若需透明需自定义扩展; - 性能优化:在资源有限的嵌入式设备上,建议将色环尺寸控制在 150~250px 之间,避免过大导致渲染卡顿。
通过色环部件,LVGL 实现了 “所见即所得” 的颜色选择体验,结合灵活的 API 和样式,能满足大多数 UI 的颜色配置需求。
LVGL按钮矩阵部件(btnmatrix)
LVGL 的按钮矩阵部件(btnmatrix)是由多个按钮组成的网格状控件,适合创建键盘、遥控器、快捷操作面板等场景。它通过 “按钮映射表” 统一管理多个按钮的文本、属性和布局,支持批量设置样式和事件处理,比单独创建多个按钮更高效。
一、核心特性
- 网格布局:通过字符串数组(按钮映射表)定义按钮排列,支持换行(
\n
)和空按钮(""
); - 批量控制:统一设置所有按钮的样式、尺寸和状态(如禁用、选中);
- 灵活属性:可单独设置某个按钮的禁用(
LV_BTNMATRIX_CTRL_DISABLED
)、选中(LV_BTNMATRIX_CTRL_CHECKABLE
)等属性; - 事件联动:支持整体或单个按钮的点击事件,方便处理用户交互。
二、基本用法示例
以下是创建一个简单数字键盘(3×3 布局)的示例,包含按钮映射、事件处理和基本样式:
#include "lvgl.h"// 按钮点击事件回调
static void btnmatrix_event_cb(lv_event_t *e) {lv_obj_t *btnmatrix = lv_event_get_target(e);lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_VALUE_CHANGED) {// 获取当前点击的按钮索引和文本uint32_t btn_idx = lv_btnmatrix_get_selected_btn(btnmatrix);const char *btn_text = lv_btnmatrix_get_btn_text(btnmatrix, btn_idx);LV_LOG_USER("点击了按钮: %s (索引: %d)", btn_text, btn_idx);}
}void btnmatrix_demo(void) {// 1. 定义按钮映射表(字符串数组,\n表示换行)static const char *btn_map[] = {"1", "2", "3", "\n", // 第一行:1 2 3"4", "5", "6", "\n", // 第二行:4 5 6"7", "8", "9", "\n", // 第三行:7 8 9"*", "0", "#", // 第四行:* 0 #"" // 必须以空字符串结尾};// 2. 创建按钮矩阵对象lv_obj_t *btnmatrix = lv_btnmatrix_create(lv_scr_act());// 3. 设置按钮映射表lv_btnmatrix_set_map(btnmatrix, btn_map);// 4. 设置按钮矩阵尺寸(宽240px,高200px)lv_obj_set_size(btnmatrix, 240, 200);// 5. 居中显示lv_obj_center(btnmatrix);// 6. 添加事件回调(监听按钮点击)lv_obj_add_event_cb(btnmatrix, btnmatrix_event_cb, LV_EVENT_VALUE_CHANGED, NULL);// 7. (可选)设置按钮间隙(像素)lv_obj_set_style_btn_gap(btnmatrix, 5, LV_PART_MAIN);
}
三、关键 API 函数
按钮矩阵的核心操作围绕 “按钮映射表”“按钮属性” 和 “事件” 展开,常用 API 如下:
功能分类 | API 函数 | 说明 |
---|---|---|
创建与布局 | lv_obj_t *lv_btnmatrix_create(lv_obj_t *parent) | 创建按钮矩阵对象。 |
void lv_btnmatrix_set_map(lv_obj_t *obj, const char *map[]) | 设置按钮映射表(字符串数组,以空字符串结尾,\n 换行)。 | |
按钮属性 | void lv_btnmatrix_set_btn_ctrl(lv_obj_t *obj, uint32_t btn_id, lv_btnmatrix_ctrl_t ctrl) | 为指定索引的按钮设置属性(如禁用、选中)。 |
void lv_btnmatrix_clear_btn_ctrl(lv_obj_t *obj, uint32_t btn_id, lv_btnmatrix_ctrl_t ctrl) | 清除指定按钮的属性。 | |
状态获取 | uint32_t lv_btnmatrix_get_selected_btn(lv_obj_t *obj) | 获取当前点击的按钮索引(LV_EVENT_VALUE_CHANGED 事件中有效)。 |
const char *lv_btnmatrix_get_btn_text(lv_obj_t *obj, uint32_t btn_id) | 获取指定索引按钮的文本。 | |
样式与布局 | void lv_obj_set_style_btn_gap(lv_obj_t *obj, lv_coord_t value, lv_part_t part) | 设置按钮之间的间隙(像素)。 |
void lv_btnmatrix_set_one_checked(lv_obj_t *obj, bool en) | 启用 “单选模式”(一次只能选中一个按钮)。 |
四、按钮属性(lv_btnmatrix_ctrl_t
)
通过 lv_btnmatrix_set_btn_ctrl()
可单独设置某个按钮的属性,常用属性:
属性常量 | 说明 |
---|---|
LV_BTNMATRIX_CTRL_DISABLED | 禁用按钮(不可点击,样式变灰)。 |
LV_BTNMATRIX_CTRL_CHECKABLE | 按钮可选中(点击后保持选中状态,需配合 LV_EVENT_VALUE_CHANGED 事件)。 |
LV_BTNMATRIX_CTRL_CHECKED | 强制设置按钮为选中状态(需先开启 LV_BTNMATRIX_CTRL_CHECKABLE )。 |
LV_BTNMATRIX_CTRL_HIDDEN | 隐藏按钮(不显示,不占空间)。 |
LV_BTNMATRIX_CTRL_NO_REPEAT | 禁用长按重复触发事件(默认长按会连续触发)。 |
示例:设置按钮属性
// 禁用索引为3的按钮(即“4”)
lv_btnmatrix_set_btn_ctrl(btnmatrix, 3, LV_BTNMATRIX_CTRL_DISABLED);// 使索引为4的按钮(即“5”)可选中
lv_btnmatrix_set_btn_ctrl(btnmatrix, 4, LV_BTNMATRIX_CTRL_CHECKABLE);// 强制选中索引为4的按钮
lv_btnmatrix_set_btn_ctrl(btnmatrix, 4, LV_BTNMATRIX_CTRL_CHECKED);
五、样式自定义
按钮矩阵包含多个可样式化的部件(part),通过 lv_obj_add_style()
设置:
部件部分(Part) | 说明 | 常用样式属性 |
---|---|---|
LV_PART_MAIN | 按钮矩阵背景 | bg_color (背景色)、border_color (边框色)、btn_gap (按钮间隙)。 |
LV_PART_ITEMS | 所有按钮的默认样式 | bg_color (按钮背景色)、text_color (按钮文本色)、border_width (按钮边框)。 |
LV_PART_ITEMS + LV_STATE_PRESSED | 按钮按下状态 | bg_color (按下时背景色)、text_color (按下时文本色)。 |
LV_PART_ITEMS + LV_STATE_DISABLED | 按钮禁用状态 | bg_color (禁用时背景色)、text_color (禁用时文本色)。 |
样式示例:深色主题按钮矩阵
void btnmatrix_styled_demo(void) {static const char *btn_map[] = {"OK", "Cancel", "\n", "Apply", "Reset", ""};lv_obj_t *btnmatrix = lv_btnmatrix_create(lv_scr_act());lv_btnmatrix_set_map(btnmatrix, btn_map);lv_obj_set_size(btnmatrix, 200, 150);// 初始化样式static lv_style_t style_main, style_btn, style_btn_pressed;lv_style_init(&style_main);lv_style_init(&style_btn);lv_style_init(&style_btn_pressed);// 背景样式(深灰色)lv_style_set_bg_color(&style_main, lv_color_hex(0x222222));lv_style_set_border_width(&style_main, 2);lv_style_set_border_color(&style_main, lv_color_hex(0x444444));lv_style_set_btn_gap(&style_main, 3); // 按钮间隙3px// 按钮默认样式(灰色)lv_style_set_bg_color(&style_btn, lv_color_hex(0x555555));lv_style_set_text_color(&style_btn, lv_color_white());lv_style_set_radius(&style_btn, 4); // 按钮圆角4px// 按钮按下样式(蓝色)lv_style_set_bg_color(&style_btn_pressed, lv_color_hex(0x0066CC));// 应用样式lv_obj_add_style(btnmatrix, &style_main, LV_PART_MAIN);lv_obj_add_style(btnmatrix, &style_btn, LV_PART_ITEMS);lv_obj_add_style(btnmatrix, &style_btn_pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
}
六、典型应用场景
- 数字键盘:如计算器、密码输入界面(如示例中的 3×3 数字键);
- 遥控器面板:电视 / 空调遥控器的功能按键矩阵;
- 快捷操作区:批量放置常用功能按钮(如 “保存”“取消”“重置”);
- 游戏控制器:方向键 + 功能键的组合布局。
七、注意事项
- 按钮映射表格式:必须以空字符串(
""
)结尾,\n
表示换行,空按钮用""
表示; - 索引计算:按钮索引从 0 开始,按行优先顺序排列(如第一行按钮索引为 0,1,2...,第二行为下一组数字);
- 性能优化:按钮数量过多时(如 10×10 以上),建议减少动画效果,避免卡顿;
- 样式继承:按钮矩阵的按钮样式默认继承自矩阵本身,可通过
LV_PART_ITEMS
单独定制。
通过按钮矩阵,可快速实现复杂的按钮布局,减少代码冗余,是 LVGL 中高效且灵活的控件之一。
LVGL文本区域部件(textarea)
LVGL 的文本区域部件(textarea)是用于多行文本输入与显示的交互控件,支持换行、滚动、密码隐藏、输入限制等功能,适用于聊天输入框、备注编辑、表单填写等场景。它在功能上扩展了标签(label)部件,增加了输入交互能力。
一、核心特性
- 多行输入:自动换行或横向滚动,支持任意长度文本;
- 输入控制:可限制最大输入长度、禁止特殊字符、设置密码模式(用 * 或其他字符隐藏内容);
- 交互反馈:包含光标(闪烁提示输入位置)、选中文本(长按可选择复制 / 剪切);
- 滚动支持:文本过长时自动出现滚动条,支持触摸或键盘滚动;
- 事件联动:输入变化、光标移动、编辑状态改变时触发事件,方便联动虚拟键盘等部件。
二、基本用法示例
以下是创建文本区域并实现基本输入功能的示例,包含初始文本设置、输入限制和事件回调:
#include "ptm_demo1.h"
#include "stdio.h"
#include "string.h"
#include "math.h"// 文本输入变化事件回调
static void textarea_event_cb(lv_event_t *e) {lv_obj_t *textarea = lv_event_get_target(e);lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_VALUE_CHANGED) {// 获取当前输入的文本const char *text = lv_textarea_get_text(textarea);LV_LOG_USER("当前文本: %s (长度: %d)", text, strlen(text));}else if (code == LV_EVENT_PRESSED) {// 编辑完成(如按下回车或失去焦点)LV_LOG_USER("编辑完成");}
}void ptm_demo(void)
{// 1. 创建文本区域对象lv_obj_t *textarea = lv_textarea_create(lv_scr_act());// 2. 设置初始文本lv_textarea_set_text(textarea, "INPUT...");// 3. 设置尺寸和位置(宽300px,高150px,居中显示)lv_obj_set_size(textarea, 300, 150);lv_obj_center(textarea);// 4. 设置最大输入长度(限制为100字符)lv_textarea_set_max_length(textarea, 100);// 5. 添加事件回调(监听输入变化和编辑完成)lv_obj_add_event_cb(textarea, textarea_event_cb, LV_EVENT_VALUE_CHANGED, NULL);lv_obj_add_event_cb(textarea, textarea_event_cb, LV_EVENT_PRESSED, NULL);}
三、关键 API 函数
文本区域的核心 API 围绕 “文本操作”“输入控制”“交互设置” 展开,常用函数如下:
功能分类 | API 函数 | 说明 |
---|---|---|
文本操作 | void lv_textarea_set_text(lv_obj_t *obj, const char *txt) | 设置文本区域的初始文本。 |
const char *lv_textarea_get_text(lv_obj_t *obj) | 获取当前输入的文本。 | |
void lv_textarea_add_text(lv_obj_t *obj, const char *txt) | 在现有文本后追加内容。 | |
void lv_textarea_clear(lv_obj_t *obj) | 清空文本区域内容。 | |
输入限制 | void lv_textarea_set_max_length(lv_obj_t *obj, uint32_t len) | 设置最大输入长度(0 表示无限制)。 |
void lv_textarea_set_accepted_chars(lv_obj_t *obj, const char *chars) | 限制允许输入的字符(如 "0123456789" 仅允许数字)。 | |
模式设置 | void lv_textarea_set_password_mode(lv_obj_t *obj, bool en) | 启用密码模式(文本将被 * 或其他字符替代显示)。 |
void lv_textarea_set_password_char(lv_obj_t *obj, char c) | 自定义密码模式的替代字符(默认是 '*')。 | |
光标控制 | void lv_textarea_set_cursor_pos(lv_obj_t *obj, uint32_t pos) | 设置光标位置(0 表示开头,LV_TEXTAREA_CURSOR_LAST 表示末尾)。 |
void lv_textarea_set_cursor_blink(lv_obj_t *obj, bool en) | 启用 / 禁用光标闪烁(默认启用)。 | |
滚动控制 | void lv_textarea_scroll_to_cursor(lv_obj_t *obj) | 自动滚动到光标位置(确保光标可见)。 |
四、样式自定义
文本区域包含多个可样式化的部件(part),通过 lv_obj_add_style()
可定制外观,常用 part 及样式属性:
部件部分(Part) | 说明 | 常用样式属性 |
---|---|---|
LV_PART_MAIN | 文本区域背景 | bg_color (背景色)、border_color (边框色)、border_width (边框宽度)、padding (内边距)。 |
LV_PART_CURSOR | 输入光标 | bg_color (光标颜色)、width (光标宽度)、height (光标高度,默认文本行高)。 |
LV_PART_PLACEHOLDER | 占位文本(无内容时显示) | text_color (占位文本颜色,默认灰色)、text_font (占位文本字体)。 |
LV_PART_SELECTED | 选中文本 | bg_color (选中背景色,默认蓝色)、text_color (选中文本色,默认白色)。 |
样式示例:深色主题文本区域
void textarea_styled_demo(void) {lv_obj_t *textarea = lv_textarea_create(lv_scr_act());lv_textarea_set_text(textarea, ""); // 初始为空lv_textarea_set_placeholder_text(textarea, "请输入密码..."); // 占位文本lv_textarea_set_password_mode(textarea, true); // 密码模式lv_obj_set_size(textarea, 250, 80);lv_obj_center(textarea);// 初始化样式static lv_style_t style_main, style_cursor, style_placeholder;lv_style_init(&style_main);lv_style_init(&style_cursor);lv_style_init(&style_placeholder);// 背景样式(深灰底色+蓝色边框)lv_style_set_bg_color(&style_main, lv_color_hex(0x222222));lv_style_set_border_color(&style_main, lv_color_hex(0x0066CC));lv_style_set_border_width(&style_main, 2);lv_style_set_padding(&style_main, 10); // 内边距10px// 光标样式(红色+宽度2px)lv_style_set_bg_color(&style_cursor, lv_color_hex(0xFF3333));lv_style_set_width(&style_cursor, 2);// 占位文本样式(浅灰色)lv_style_set_text_color(&style_placeholder, lv_color_hex(0xAAAAAA));// 应用样式lv_obj_add_style(textarea, &style_main, LV_PART_MAIN);lv_obj_add_style(textarea, &style_cursor, LV_PART_CURSOR);lv_obj_add_style(textarea, &style_placeholder, LV_PART_PLACEHOLDER);
}
五、高级功能
-
与虚拟键盘联动文本区域获得焦点时自动弹出虚拟键盘(
lv_keyboard
),输入完成后关闭:// 创建虚拟键盘 lv_obj_t *keyboard = lv_keyboard_create(lv_scr_act()); // 将键盘与文本区域绑定 lv_keyboard_set_textarea(keyboard, textarea);
-
自动换行与滚动默认启用自动换行,可通过样式控制文本对齐方式:
// 设置文本左对齐(默认) lv_obj_set_style_text_align(textarea, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN);
-
选中文本操作长按文本区域可触发选中文本,通过 API 获取选中内容:
// 获取选中文本的起始和结束位置 uint32_t start, end; lv_textarea_get_selection(textarea, &start, &end); // 提取选中的子串(需自行实现字符串截取)
六、注意事项
- 内存占用:长文本(如超过 1000 字符)会占用较多内存,建议按需限制长度;
- 光标位置:动态修改文本后,需调用
lv_textarea_scroll_to_cursor()
确保光标可见; - 密码模式:启用后文本会被隐藏,但
lv_textarea_get_text()
仍返回原始内容,需注意安全; - 输入性能:在资源有限的设备上,避免频繁更新文本(如每输入一个字符就触发重绘)。
文本区域是 LVGL 中处理多行输入的核心部件,通过灵活的 API 和样式定制,可满足从简单备注到复杂表单的各种输入需求。
LVGL键盘部件(keyboard)
LVGL 的键盘部件(keyboard)是专为触摸屏设备设计的虚拟输入工具,用于配合文本输入控件(如textarea
、textfield
)实现文字输入。它支持多种布局(字母、数字、符号)、自定义按键样式和动态切换模式,是嵌入式 GUI 中处理用户输入的核心部件。
一、核心特性
- 多布局支持:内置字母(大小写)、数字、符号等预设布局,也可自定义按键映射;
- 自动联动:与文本输入控件绑定后,输入内容会自动同步到目标控件,无需额外处理;
- 动态切换:支持通过按键切换输入模式(如字母↔数字),并自动更新键盘布局;
- 样式定制:可自定义按键颜色、字体、大小、间隙,以及特殊按键(如回车、删除)的外观;
- 事件反馈:支持按键按下、释放、布局切换等事件,方便实现输入限制或交互反馈。
二、基本用法示例
以下是键盘与文本区域联动的基础示例,包含创建键盘、绑定输入控件、切换布局等功能:
// 创建虚拟键盘对象,父对象为当前活动屏幕(lv_scr_act()返回当前显示的屏幕)
// 键盘会被初始化为默认样式和布局(通常为小写字母模式)
lv_obj_t *kb = lv_keyboard_create(lv_scr_act());// 创建文本区域对象(多行文本输入控件),父对象为当前活动屏幕
// 用于接收键盘输入的内容,是键盘的输入目标
lv_obj_t *ta = lv_textarea_create(lv_scr_act());// 将虚拟键盘与文本区域绑定
// 绑定后,键盘输入的字符会自动同步到文本区域,无需额外处理输入逻辑
// 同时文本区域获取焦点时,键盘会自动关联;文本区域失去焦点时,输入终止
lv_keyboard_set_textarea(kb, ta);// 启用键盘的"弹出提示"功能(popovers)
// 启用后,长按某些按键(如字母键)会弹出包含更多关联字符的小窗口
// 例如:长按"e"可能弹出"è"、"é"、"ê"等变体字符,提升输入灵活性
lv_keyboard_set_popovers(kb, true);
LVGL图片按钮部件(imgbtn)
LVGL 的图片按钮部件(imgbtn)是一种完全通过图片展示状态的交互控件,适用于需要自定义视觉效果的按钮场景(如工具栏图标、导航按钮等)。它没有默认文本,而是通过不同状态的图片(默认、按下、选中、禁用等)提供交互反馈,比普通按钮(btn)更注重视觉表达。
一、核心特性
- 多状态图片支持:为默认、按下、选中、禁用等状态分别设置不同图片,自动根据状态切换;
- 无默认样式:完全依赖图片定义外观,不包含默认背景或边框,适合高度定制的 UI;
- 交互反馈:支持点击、长按等事件,状态变化时自动切换对应图片;
- 图片来源灵活:可使用内置符号(
LV_SYMBOL_*
)、外部图片文件或画布绘制的图像作为按钮内容。
二、基本用法示例
以下是创建图片按钮并设置不同状态图片的示例,使用 LVGL 内置符号作为图片源(方便演示,实际可替换为自定义图片):
图片按钮的核心操作围绕 “状态管理” 和 “图片设置” 展开,常用 API 如下:
功能分类 | API 函数 | 说明 |
---|---|---|
创建与基础设置 | lv_obj_t *lv_imgbtn_create(lv_obj_t *parent) | 创建图片按钮对象。 |
void lv_obj_set_size(lv_obj_t *obj, lv_coord_t w, lv_coord_t h) | 设置按钮尺寸(需与图片尺寸匹配,避免拉伸或裁剪)。 | |
图片设置 | void lv_imgbtn_set_src(lv_obj_t *obj, lv_imgbtn_state_t state, const void *src, const void *src_pressed, const void *src_disabled) | 为指定状态设置图片。src 为默认图片,src_pressed 为按下时的图片(可选),src_disabled 为禁用时的图片(可选)。 |
状态管理 | void lv_obj_set_state(lv_obj_t *obj, lv_state_t state) | 设置按钮状态(如LV_STATE_PRESSED 按下、LV_STATE_CHECKED 选中、LV_STATE_DISABLED 禁用)。 |
bool lv_obj_has_state(lv_obj_t *obj, lv_state_t state) | 检查按钮是否处于指定状态。 | |
交互设置 | void lv_obj_add_flag(lv_obj_t *obj, lv_obj_flag_t flag) | 添加标志,如LV_OBJ_FLAG_CHECKABLE 启用选中状态(允许按钮在选中 / 未选中间切换)。 |
LVGL选项卡部件(tabview)
LVGL 的选项卡部件(tabview)是一种多页面内容管理控件,通过顶部 / 底部的标签栏切换不同内容页面,适合在有限空间内展示多个相关模块(如设置界面、数据统计、功能分类等)。它自动管理页面切换逻辑和动画效果,比手动创建多个页面更高效。
一、核心特性
- 多页面组织:一个选项卡控件可包含多个页面(tab),每个页面独立承载内容;
- 标签切换:通过点击标签栏的文本 / 图标切换页面,支持动画过渡效果;
- 灵活布局:标签栏可位于顶部(默认)或底部,支持自定义标签样式;
- 页面管理:可动态添加 / 删除页面、设置默认显示页面、禁用特定标签;
- 事件反馈:页面切换时触发事件,方便联动更新数据或执行初始化逻辑。
二、基本用法示例
// 创建选项卡控件(tabview),父对象为当前活动屏幕(lv_scr_act()返回当前显示的屏幕)
// 采用默认参数:标签栏高度自动计算,标签栏位置默认在顶部
lv_obj_t *tabview = lv_tabview_create(lv_scr_act());// 给选项卡控件添加第一个页面(tab)
// 参数:选项卡对象(tabview)、标签文本("Tab 1")
// 返回值:该页面对象(tab1),后续可通过此对象向页面添加内容(如标签、按钮等)
lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1");// 给选项卡控件添加第二个页面,标签文本为"Tab 2"
// 返回页面对象tab2,用于承载第二个页面的内容
lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2");// 给选项卡控件添加第三个页面,标签文本为"Tab 3"
// 返回页面对象tab3,用于承载第三个页面的内容
lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3");
LVGL平铺视图部件(tileview)
LVGL 的平铺视图部件(tileview)是一种支持滑动切换的多页面容器,通过 “瓦片(tile)” 形式组织多个页面,用户可通过触摸横向 / 纵向滑动在不同瓦片间导航。它适合展示关联性弱但需要快速切换的内容(如图片浏览、多模块数据展示、步骤导航等),比选项卡(tabview)更灵活,支持任意方向的页面扩展。
一、核心特性
- 多瓦片布局:可按行列排列多个瓦片(如 2×2、3×1 等),每个瓦片是独立的内容容器;
- 滑动导航:支持横向(左右)和纵向(上下)滑动切换瓦片,自动处理滑动边界;
- 边缘提示:滑动到边界时可显示边缘闪烁效果,提示用户已到达尽头;
- 动画过渡:瓦片切换时带有平滑的滑动动画,提升交互体验;
- 灵活定位:可直接跳转到指定行列的瓦片,支持禁用特定方向的滑动。
二、基本用法示例
以下是创建 2×2 布局的平铺视图示例,包含 4 个瓦片,每个瓦片添加不同内容,并支持滑动切换:
#include "ptm_demo1.h"
#include "stdio.h"
#include "string.h"
#include "math.h"void ptm_demo(void)
{// 1. 创建平铺视图对象(父对象为当前屏幕)lv_obj_t *tileview = lv_tileview_create(lv_scr_act());// 3. 添加瓦片(按行列布局,行和列从0开始索引)// 参数:tileview对象、行索引、列索引、是否允许横向滑动、是否允许纵向滑动lv_obj_t *tile_0_0 = lv_tileview_add_tile(tileview, 0, 0, LV_DIR_HOR | LV_DIR_VER); // 0行0列,允许横纵滑动lv_obj_t *tile_0_1 = lv_tileview_add_tile(tileview, 0, 1, LV_DIR_HOR | LV_DIR_VER); // 0行1列lv_obj_t *tile_1_0 = lv_tileview_add_tile(tileview, 1, 0, LV_DIR_HOR | LV_DIR_VER); // 1行0列lv_obj_t *tile_1_1 = lv_tileview_add_tile(tileview, 1, 1, LV_DIR_HOR | LV_DIR_VER); // 1行1列// 4. 为每个瓦片添加内容(以标签为例,区分不同瓦片)// 瓦片(0,0)内容lv_obj_t *label_0_0 = lv_label_create(tile_0_0);lv_label_set_text(label_0_0, "1");lv_obj_center(label_0_0);// 瓦片(0,1)内容lv_obj_t *label_0_1 = lv_label_create(tile_0_1);lv_label_set_text(label_0_1, "2");lv_obj_center(label_0_1);// 瓦片(1,0)内容lv_obj_t *label_1_0 = lv_label_create(tile_1_0);lv_label_set_text(label_1_0, "3");lv_obj_center(label_1_0);// 瓦片(1,1)内容lv_obj_t *label_1_1 = lv_label_create(tile_1_1);lv_label_set_text(label_1_1, "4");lv_obj_center(label_1_1);}
LVGL窗口部件(win)
LVGL 的窗口部件(win)是一种可移动、带标题栏的容器控件,适合展示临时内容(如弹窗、设置面板、详情页等)。它包含标题栏(可带关闭按钮)和内容区,支持拖拽移动、关闭操作,且能自动处理与其他控件的层级关系(始终显示在顶层)。
一、核心特性
- 标题栏:顶部区域,可显示标题文本和关闭按钮,支持点击拖拽移动窗口;
- 内容区:用于放置具体内容(如按钮、文本、表单等),尺寸可自定义;
- 关闭功能:默认带关闭按钮(×),点击可触发关闭事件;
- 移动支持:通过拖拽标题栏可移动窗口,自动限制在父容器范围内;
- 层级管理:窗口创建后自动置于顶层,避免被其他控件遮挡。
二、基本用法示例
以下是创建窗口并添加内容的示例,包含标题栏、关闭按钮、内容区,并实现关闭窗口的功能:
// 创建窗口对象,父容器为当前活动屏幕(lv_scr_act()返回当前显示的屏幕)
// 窗口默认包含标题栏和内容区,初始样式为基础风格
lv_obj_t *win = lv_win_create(lv_scr_act());// 设置窗口的尺寸:宽度300像素,高度200像素
// 尺寸包含标题栏和内容区的整体大小
lv_obj_set_size(win, 300, 200);// 将窗口在其父容器(屏幕)中居中显示
lv_obj_center(win);// 为窗口的默认状态(LV_STATE_DEFAULT)设置边框宽度为1像素
// 边框会围绕整个窗口(包括标题栏和内容区)显示
lv_obj_set_style_border_width(win, 1, LV_STATE_DEFAULT);// 向窗口的标题栏添加标题文本"Setting"
// 返回值为标题文本对象(可用于进一步修改标题样式,如字体、颜色等)
lv_obj_t *title = lv_win_add_title(win, "Setting");// 向窗口的标题栏添加按钮,按钮显示内容为LVGL内置的关闭符号(×),按钮尺寸为20x20像素
// 通常用于关闭窗口(需额外绑定点击事件实现关闭功能)
lv_obj_t *btn = lv_win_add_button(win, LV_SYMBOL_CLOSE, 20);// 获取窗口的内容区对象(窗口内部用于承载实际内容的区域,不包含标题栏)
// 所有需要显示的内容(如标签、按钮、输入框等)都应添加到内容区,而非窗口本身
lv_obj_t *content = lv_win_get_content(win);// 在内容区中创建一个标签控件(用于显示文本)
// 标签的父对象是内容区,因此会被限制在内容区范围内显示
lv_obj_t *label = lv_label_create(content);
LVGL消息框部件(msgbox)
LVGL 的消息框部件(msgbox)是一种预定义的模态对话框,专为展示提示信息、确认操作或错误反馈设计。它继承了窗口(win)的特性,自带标题栏、文本区域和按钮组,支持阻塞式交互(用户必须点击按钮才能继续),是快速实现弹窗交互的高效工具。
一、核心特性
- 固定结构:包含标题、消息文本和按钮组(1-3 个按钮),布局自动调整;
- 模态显示:显示时阻塞其他控件交互,强制用户关注并响应;
- 自动布局:文本和按钮会根据内容自动排版,无需手动调整位置;
- 简化交互:按钮点击后自动关闭消息框,无需额外处理关闭逻辑;
- 风格统一:默认样式与系统风格一致,也可自定义外观。
二、基本用法示例
以下是创建确认消息框的示例,包含标题、提示文本和两个按钮(“确认”“取消”),并处理按钮点击事件:
#include "lvgl.h"// 消息框按钮点击事件回调
static void msgbox_btn_cb(lv_event_t *e) {lv_obj_t *msgbox = lv_event_get_user_data(e);lv_obj_t *btn = lv_event_get_target(e);const char *btn_text = lv_label_get_text(lv_obj_get_child(btn, 0)); // 获取按钮文本// 根据按钮文本执行不同逻辑if (strcmp(btn_text, "确认") == 0) {LV_LOG_USER("用户点击了确认");// 执行确认操作(如删除文件、提交数据等)} else if (strcmp(btn_text, "取消") == 0) {LV_LOG_USER("用户点击了取消");// 执行取消操作}// 关闭消息框(按钮点击后必须手动删除,或在创建时设置自动关闭)lv_obj_del(msgbox);
}void msgbox_demo(void) {// 1. 定义按钮文本(最多3个按钮,以NULL结束)static const char *btn_texts[] = {"确认", "取消", NULL};// 2. 创建消息框// 参数:父对象(屏幕)、标题、消息文本、按钮文本数组、是否自动关闭(false=手动关闭)lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),"操作确认", // 标题"确定要删除此文件吗?\n删除后无法恢复。", // 消息文本(支持换行)btn_texts, // 按钮文本数组false // 不自动关闭);// 3. 设置消息框尺寸(可选,不设置则自适应内容)lv_obj_set_width(msgbox, 280); // 固定宽度,高度自适应// 4. 为所有按钮绑定点击事件uint32_t btn_cnt = lv_obj_get_child_count(lv_msgbox_get_btns(msgbox));for (uint32_t i = 0; i < btn_cnt; i++) {lv_obj_t *btn = lv_obj_get_child(lv_msgbox_get_btns(msgbox), i);lv_obj_add_event_cb(btn, msgbox_btn_cb, LV_EVENT_CLICKED, msgbox);}}
LVGL微调器部件(spinbox)
LVGL 的微调器部件(spinbox)是一种专为数字输入设计的交互控件,结合了文本输入框和加减按钮,允许用户通过点击按钮或直接输入来调整数值。它适合需要精确数字输入的场景(如参数设置、数量选择、时间调整等),支持范围限制、步长设置和数值格式化,比普通文本框更高效、更不易出错。
一、核心特性
- 双向调整:通过 “+”“-” 按钮逐步增减数值,或直接输入数字;
- 范围限制:可设置允许输入的最小值和最大值,超出范围自动截断;
- 步长控制:定义每次点击按钮时数值的增减幅度(如每次 + 1、+0.5 等);
- 格式支持:支持整数、浮点数(小数位数可控),以及自定义数值格式;
- 输入验证:自动过滤非数字输入,确保输入合法性;
- 事件反馈:数值变化时触发事件,方便实时处理调整后的数值。
二、基本用法示例
以下是创建数字微调器的示例,包含范围限制、步长设置、数值初始化,并监听数值变化事件:
#include "lvgl.h"// 微调器数值变化事件回调
static void spinbox_event_cb(lv_event_t *e) {lv_obj_t *spinbox = lv_event_get_target(e);lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_VALUE_CHANGED) {// 获取当前数值(整数)int32_t value = lv_spinbox_get_value(spinbox);LV_LOG_USER("微调器数值变化:%d", value);}
}void spinbox_demo(void) {// 1. 创建微调器对象lv_obj_t *spinbox = lv_spinbox_create(lv_scr_act());// 2. 设置数值范围(1-100)lv_spinbox_set_range(spinbox, 1, 100);// 3. 设置步长(每次点击+/-按钮增减5)lv_spinbox_set_step(spinbox, 5);// 4. 设置初始数值(30)lv_spinbox_set_value(spinbox, 30);// 5. 设置输入模式(仅允许数字输入,默认已启用)lv_spinbox_set_accepted_chars(spinbox, "0123456789");// 6. 添加数值变化事件回调lv_obj_add_event_cb(spinbox, spinbox_event_cb, LV_EVENT_VALUE_CHANGED, NULL);// 7. 设置尺寸和位置(宽120px,高40px,居中显示)lv_obj_set_size(spinbox, 120, 40);lv_obj_center(spinbox);
}
LVGL表格部件(table)
LVGL 的微调器部件(spinbox)是一种专为数字输入设计的交互控件,结合了文本输入框和加减按钮,允许用户通过点击按钮或直接输入来调整数值。它适合需要精确数字输入的场景(如参数设置、数量选择、时间调整等),支持范围限制、步长设置和数值格式化,比普通文本框更高效、更不易出错。
一、核心特性
- 双向调整:通过 “+”“-” 按钮逐步增减数值,或直接输入数字;
- 范围限制:可设置允许输入的最小值和最大值,超出范围自动截断;
- 步长控制:定义每次点击按钮时数值的增减幅度(如每次 + 1、+0.5 等);
- 格式支持:支持整数、浮点数(小数位数可控),以及自定义数值格式;
- 输入验证:自动过滤非数字输入,确保输入合法性;
- 事件反馈:数值变化时触发事件,方便实时处理调整后的数值。
二、基本用法示例
以下是创建数字微调器的示例,包含范围限制、步长设置、数值初始化,并监听数值变化事件:
#include "lvgl.h"// 表格单元格点击事件回调
static void table_event_cb(lv_event_t *e) {lv_obj_t *table = lv_event_get_target(e);lv_event_code_t code = lv_event_get_code(e);if (code == LV_EVENT_CELL_CLICKED) {// 获取点击的单元格坐标(行、列)uint32_t row, col;lv_table_get_selected_cell(table, &row, &col);// 获取单元格内容const char *cell_text = lv_table_get_cell_value(table, row, col);LV_LOG_USER("点击单元格:行=%d, 列=%d, 内容=%s", row, col, cell_text);}
}void table_demo(void) {// 1. 创建表格对象lv_obj_t *table = lv_table_create(lv_scr_act());// 2. 设置表格行列数(3行3列)lv_table_set_row_cnt(table, 3); // 3行(含表头)lv_table_set_col_cnt(table, 3); // 3列// 3. 设置列宽(第0列80px,第1列100px,第2列60px)lv_table_set_col_width(table, 0, 80);lv_table_set_col_width(table, 1, 100);lv_table_set_col_width(table, 2, 60);// 4. 填充单元格内容(行、列从0开始索引)// 表头(第0行)lv_table_set_cell_value(table, 0, 0, "ID"); // 第0行第0列lv_table_set_cell_value(table, 0, 1, "名称"); // 第0行第1列lv_table_set_cell_value(table, 0, 2, "数量"); // 第0行第2列// 数据行(第1行)lv_table_set_cell_value(table, 1, 0, "001");lv_table_set_cell_value(table, 1, 1, "产品A");lv_table_set_cell_value(table, 1, 2, "25");// 数据行(第2行)lv_table_set_cell_value(table, 2, 0, "002");lv_table_set_cell_value(table, 2, 1, "产品B");lv_table_set_cell_value(table, 2, 2, "18");// 5. 启用单元格点击事件(默认关闭)lv_obj_add_flag(table, LV_OBJ_FLAG_CLICKABLE);lv_obj_add_event_cb(table, table_event_cb, LV_EVENT_CELL_CLICKED, NULL);// 6. 设置表格尺寸和位置(宽240px,高120px,居中显示)lv_obj_set_size(table, 240, 120);lv_obj_center(table);
}