[ LVGL ] 入门

一、简介定位


LVGL(Light and Versatile Graphics Library,轻量多功能图形库) 是一个专为资源受限的嵌入式设备打造的开源 GUI 框架,像 STM32、RTOS、裸机系统都能用。它能帮你 快速搭建像手机 App 那样的漂亮界面,但内存占用却非常小,适合用在小 MCU 上。按钮、滑块、动画、触摸响应这些功能,LVGL 都已经帮你封装好了 —— 就像你在做一个嵌入式 App,而不是一块板子上的界面

二、运转机制


(一)引擎架构


要让 LVGL 跑起来,本质上只靠三样东西:输入、输出、时间。你把这三样供上,剩下的事它全包 —— 包括界面构建、事件响应、动画刷新,全流程自动完成。

具体来看,这三样分别对应:

  1. 输入接口(Input): 接收用户操作(触摸、按键),就像用户在说话,LVGL 靠它来听懂。

  2. 显示驱动(Display): 把界面内容画到实际的 LCD 上,LVGL 像设计师出图纸,驱动像粉刷匠照图刷墙,而你(开发者)是施工队长,负责搭接口、发指令,让图纸变成现实。

  3. 时间驱动(Tick): 通过定时调用 lv_timer_handler() 提供时钟节拍,相当于给系统上发条,不上发条,动画和事件就不会动。

此外还有两个内部模块也很关键:

  • 控件树(Widget Tree): 界面控件按父子结构组织,像套娃一样层层嵌套,逻辑清晰,便于管理。

  • 事件与动画系统: 操作触发事件、控件响应动作,动画播放平滑流畅,交互体验全由 LVGL 接手处理。

你喂它输入、输出、时间,它就能全自动完成响应用户 → 更新控件 → 显示界面这一整套链路。简单来说:输入进来 → LVGL 处理 → 显示出来,以下是该流程的示意图:

Alt
那么问题来了 —— 你喂给 LVGL 的时间到底是干什么用的?其实,每次界面要动起来、动画要刷新、控件要响应事件,背后都是靠你定时调用的那个函数:lv_timer_handler()。它就像 LVGL 的主心跳,每调一次,系统就动一下,把界面该处理的事都安排一遍。

(二)循环剖析


在 LVGL 里,有一个核心函数叫 lv_timer_handler()你需要定时调用它,比如每 5 毫秒跑一次。可以把它看作是 LVGL 的心跳或 大脑主循环,每调用一次,LVGL 就完成一轮处理流程

那么这一轮都干了什么?大致包括这些:

  1. 读取输入设备: 看看用户有没有点触摸屏、按了按键;
  2. 刷新显示内容: 如果有控件变了,或者该重画了,它就会触发重绘;
  3. 处理动画效果: 比如按钮弹一下、滑块滑动等;
  4. 触发事件回调: 如果某个控件注册了点击之类的事件,就会在这里被触发;
  5. 执行用户定时器: 你自己加的 lv_timer_t 类型的定时器,也会在这一步统一调度。

lv_timer_handler() 是 LVGL 运转的中枢,你 定时调它,LVGL 就能自动响应输入、刷新控件、播放动画、执行定时任务。你只要提供输入、输出、时间,设计好界面,剩下的活它全能安排。

通俗点说,你一喊开始下一轮,LVGL 就立刻检查一下有没有人敲门(输入)、该不该刷墙(显示)、是不是有人预约了任务(定时器),然后自己把事情干完。

(三)开发范式


开发者如何真正让 LVGL 跑起来?其实流程非常清晰,只需掌握三个核心步骤:

  1. 初始化: 先初始化 LVGL 本身,并接好输入设备、显示驱动、定时器等接口;
  2. 构建界面: 使用 LVGL 提供的控件系统搭建 UI 界面,比如按钮、标签、图标等;
  3. 注册事件回调: 为控件绑定事件回调,例如按钮点击后要执行什么功能;

其余流程(包括界面重绘、动画播放、事件分发、控件管理等)都由 LVGL 内部自动完成。你只需专注于控件的创建与逻辑设计,事件调度、绘制更新、动画执行等细节将由 LVGL 自动管理。但请注意,控件对象的销毁仍需开发者显式处理,除非使用自动屏幕切换机制。

总之,你搭好舞台,演员安排好,灯光和时间也交代清楚,然后就让 LVGL 自己演出就行了。

三、关键概念


(一)显示设备和显示对象


你看到的显示设备与你操作的显示对象

概念解释
显示器(Display Panel)这是实际的屏幕硬件,也就是你用来“看”界面的那个物理设备,比如 LCD、OLED 屏。
显示对象(lv_display_t这是 LVGL 内部在内存中创建的一个结构体对象,用来管理和控制显示器,比如负责把图像“画”到屏幕上。
屏幕(Screen)是一个没有父级的根 Widget,代表一整套用户界面。它附加在某个显示对象上,用于展示你设计的各种控件。

🔎 提示: 当你第一次创建一个 lv_display 显示对象时,它会自动成为默认显示。之后很多 LVGL 的函数(比如设置哪个屏幕当前显示)会自动使用这个默认显示对象,不需要你手动指定。这让开发流程更简洁,尤其是大多数项目只用一个屏幕时。

(二)控件(Widget)


Widget 是 LVGL 中的核心概念,它们是构建 UI 的基本单元,也是用户可以交互的图形控件。例如按钮、标签、滑块、图表等,都是用 lv_obj_t* 表示。

示例:创建滑块控件示例

lv_obj_t * slider1 = lv_slider_create(lv_screen_active());
// 设置滑块控件属性:
lv_obj_set_x(slider1, 30);
lv_obj_set_size(slider1, 200, 50);
lv_slider_set_value(slider1, 70, LV_ANIM_ON);

示例:删除滑块

lv_obj_delete(slider1);

(三)控件组织结构


Widget 可以相互嵌套使用。

每个 Widget 都有一个父对象。

父子 Widget 之间具有关联关系:

  • 子控件位置相对于父控件;

  • 删除父控件将级联销毁其所有子控件;

  • 超出父控件区域的内容将被裁剪隐藏。

示例:创建标签控件并加载为屏幕

// 创建一个屏幕对象
lv_obj_t * screen = lv_obj_create(NULL);
// 在屏幕上创建标签  
lv_obj_t * label = lv_label_create(screen);  
lv_label_set_text(label, "Hello, LVGL!");
// 将该屏幕设为当前活动屏幕
lv_screen_load(screen);  

(四)屏幕切换与管理


使用以下函数可切换当前显示的活动屏幕:

lv_screen_load(new_screen);

如果你希望在切换屏幕时自动删除旧的屏幕和其子控件,可使用带动画的方式并设置自动删除参数:

// 自动删除旧屏幕
lv_screen_load_anim(new_screen, ..., true);  

支持多个屏幕缓存在内存中,便于快速切换或缓存复杂界面,提升性能。

四、事件系统


LVGL 支持将事件回调函数绑定到控件上,响应用户交互:

void my_btn_event_cb(lv_event_t * e)
{
    printf("Button clicked\n");
}

lv_obj_add_event_cb(btn, my_btn_event_cb, LV_EVENT_CLICKED, NULL);

常见事件类型包括:

  • LV_EVENT_PRESSED

  • LV_EVENT_RELEASED

  • LV_EVENT_CLICKED

  • LV_EVENT_ALL(监听全部事件,便于调试)

五、部件与状态


(一)部件(Part)


控件通常是由多个部件组成的,例如滑块控件包含:

  • 主体:LV_PART_MAIN
  • 指示条:LV_PART_INDICATOR
  • 按钮:LV_PART_KNOB

你可为每个部件设置独立样式,实现细粒度美化。

(二)状态(State)


控件可处于一种或多种状态的组合中,常见状态如下:

状态宏描述
LV_STATE_DEFAULT默认状态
LV_STATE_CHECKED被选中
LV_STATE_FOCUSED获取焦点
LV_STATE_PRESSED正在按压
LV_STATE_DISABLED已被禁用

示例:检查与设置状态

// 检查是否处于某状态
bool is_focused = lv_obj_has_state(widget, LV_STATE_FOCUSED);  
// 添加状态
lv_obj_add_state(widget, LV_STATE_CHECKED);  
// 移除状态
lv_obj_remove_state(widget, LV_STATE_PRESSED);  

六、样式


LVGL 样式(lv_style_t)定义控件视觉外观:背景色、边框、字体、透明度等。

完整设置流程

// 声明一个静态的样式对象style,用于配置UI组件的主体样式
static lv_style_t style;

// 初始化样式对象style,确保样式结构体处于可用状态
lv_style_init(&style);

// 设置style的背景颜色为十六进制值0x2080bb所代表的蓝色
lv_style_set_bg_color(&style, lv_color_hex(0x2080bb));

// 将配置好的style样式应用到指定的widget组件的主体部分(LV_PART_MAIN)
lv_obj_add_style(widget, &style, LV_PART_MAIN);

快捷设置单一属性

lv_obj_set_style_bg_color(obj, lv_color_hex(0xff0000), LV_PART_INDICATOR);

样式继承机制: 属性缺省时,控件会向父控件查找继承。

七、主题


LVGL 支持主题机制:为所有控件预设统一样式。

主题配置通过 lv_conf.h 编译配置文件控制,便于整体风格统一与自定义美化。

八、MicroPython 支持


LVGL 提供完整的 MicroPython 绑定,适用于快速原型设计和高效迭代开发。

示例:创建按钮和标签

import display_driver
import lvgl as lv

scr = lv.obj()
btn = lv.button(scr)
btn.align(lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Hello World!")
lv.screen_load(scr)

九、总结


LVGL 是一个功能强大、设计精巧、资源友好的嵌入式图形界面解决方案,无论是小型 MCU(如 STM32),还是 Linux 平台下的 SoC 系统,均可适配使用。通过其高效架构和丰富控件体系,开发者可高效构建现代化的嵌入式 GUI 应用。

如需进一步学习与实践,推荐参考以下资料:

愿你用得顺手,做出惊艳界面!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值