LVGL部件应用笔记(基于正点原子教程,持续更新)
前言
本文是基于正点原子教程的LVGL部件使用笔记,原视频链接如下
【正点原子】手把手教你学LVGL图形界面编程【真人出镜】LVGL图形界面编程视频教程 单片机 嵌入式_哔哩哔哩_bilibili
因为本文是针对部件层,想对于每个部件留下一点记录,不涉及具体芯片的移植,关于移植,其实很看具体情况,首先配置显示,触摸可选,然后提供时基。然后看项目是否要上RTOS,是否有外部RAM,是否有自研的管理算法…
本文使用Windows模拟器开发,使用版本为LVGL8.3,具体模拟器配置可看这篇文章
LVGL在VScode中安装模拟器运行配置笔记教程_vscode lvgl-CSDN博客
同时这里也可以使用Trae和Qcode,直接问AI,问题解决更快。
更新日志
首次创建并发布博客——260417
更新了几个部件——260423
在开始之前需要新建一个mygui的c文件,h文件,并在main.c的while循环前调用函数MyGui;
#include "lvgl/lvgl.h"
#include "mygui.h"
void MyGui(void)
{}
部件的基本属性
大小
C语言中没有“类”的概念,LVGL以结构体的形式来实现“类”的思维。这里先创建一个对象,显示效果为左图,当我们使用函数去定义这个对象的大小时,在下方加入一行代码,比如
lv_obj_set_size(obj, 320, 240); 显示的对象画布大小就会改变
void MyGui(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
}


API函数:
设置宽度:lv_obj_set_width(obj, new_width);
设置高度:lv_obj_set_height(obj, new_height);
同时设置宽度、高度:lv_obj_set_size(obj, new_width, new_height);
位置
这个概念也好理解,需要注意的是设置部件位置时,坐标原点在父对象的左上角
void MyGui(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 50, 50);
lv_obj_set_pos(obj, 100, 100);
}

API函数:
设置X轴坐标:lv_obj_set_x(obj, new_x);
设置Y轴坐标:lv_obj_set_y(obj, new_y);
同时设置X、Y轴坐标:lv_obj_set_pos(obj, new_x, new_y);
对齐
对齐方式有两种,一种是参照父对象对齐-左图,另一种是参照其他对象对齐(无父子关系)-右图
void MyGui(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 150, 150);
lv_obj_set_pos(obj, 50, 50);
lv_obj_t * son = lv_obj_create(obj);
lv_obj_set_size(son, 50, 50);
lv_obj_set_align(son, LV_ALIGN_CENTER);
}
void MyGui(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 150, 150);
lv_obj_set_pos(obj, 50, 50);
lv_obj_t * obj2 = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj2, 50, 50);
lv_obj_align_to(obj2, obj, LV_ALIGN_CENTER, 100, 0);
}
对齐位置有很多,这里用正点原子的图片用作参考

API:
参照父对象对齐:lv_obj_set_align(obj, LV_ALIGN_...);
参照父对象对齐,再进行偏移:lv_obj_align(obj, LV_ALIGN_..., x, y);
参照其他对象对齐(无父子关系),再进行偏移:lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y);
样式
样式用于设置部件的外观,以优化显示界面和实现用户交互。
有两种设置方式,添加普通样式和添加本地样式,我个人理解为是创建一种可以给所有对象的和仅限给单一一个对象的区别,具体可参考代码,这两个程序现象都是一样的。
void MyGui(void)
{
static lv_style_t style;
lv_style_init(&style);
lv_style_set_bg_color(&style, lv_color_hex(0xf4b183));
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 150, 150);
lv_obj_set_pos(obj, 50, 50);
lv_obj_add_style(obj, &style, LV_STATE_DEFAULT);
lv_obj_t * obj2 = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj2, 50, 50);
lv_obj_align_to(obj2, obj, LV_ALIGN_CENTER, 100, 0);
lv_obj_add_style(obj2, &style, LV_STATE_DEFAULT);
}
void MyGui(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 150, 150);
lv_obj_set_pos(obj, 50, 50);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183), LV_STATE_DEFAULT);
lv_obj_t * obj2 = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj2, 50, 50);
lv_obj_align_to(obj2, obj, LV_ALIGN_CENTER, 100, 0);
lv_obj_set_style_bg_color(obj2, lv_color_hex(0xf4b183), LV_STATE_DEFAULT);
}


什么时候样式会生效:
enum {
LV_STATE_DEFAULT = 0x0000, /* 默认状态 */
LV_STATE_CHECKED = 0x0001, /* 切换或选中状态 */
LV_STATE_FOCUSED = 0x0002, /* 通过键盘、编码器聚焦或通过触摸板、鼠标单击 */
LV_STATE_FOCUS_KEY = 0x0004, /* 通过键盘、编码器聚焦 */
LV_STATE_EDITED = 0x0008, /* 由编码器编辑 */
LV_STATE_HOVERED = 0x0010, /* 鼠标悬停(现在不支持)*/
LV_STATE_PRESSED = 0x0020, /* 已按下 */
LV_STATE_SCROLLED = 0x0040, /* 滚动状态 */
LV_STATE_DISABLED = 0x0080, /* 禁用状态 */
…
};
有哪些样式属性可以设置?
很多很多,包括但不限于,背景轮廓边框阴影等,这里举个例子,现象可见上方右图
void MyGui(void)
{
static lv_style_t style;
lv_style_init(&style);
lv_style_set_bg_color(&style, lv_color_hex(0x2196F3)); // 背景
lv_style_set_bg_opa(&style, LV_OPA_80);
lv_style_set_border_width(&style, 3);// 边框
lv_style_set_border_color(&style, lv_color_hex(0xFFFFFF));
lv_style_set_radius(&style, 15); // 圆角
lv_style_set_shadow_width(&style, 15);// 阴影
lv_style_set_shadow_ofs_x(&style, 5);
lv_style_set_shadow_ofs_y(&style, 5);
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 150, 150);
lv_obj_set_pos(obj, 50, 50);
lv_obj_add_style(obj, &style, LV_STATE_DEFAULT);
}
如何单独设置部件中某个部分的样式?
在LVGL中,单独设置部件(Widget)某个部分(Part)的样式,使用 lv_obj_set_style_xxx 函数的第3个参数(selector)来指定部件部分。
enum {
LV_PART_MAIN = 0x000000, /* 主体,像矩形一样的背景 */
LV_PART_SCROLLBAR = 0x010000, /* 滚动条 */
LV_PART_INDICATOR = 0x020000, /* 指示器,指示当前值 */
LV_PART_KNOB = 0x030000, /* 手柄或旋钮,用于调整参数值 */
LV_PART_SELECTED = 0x040000, /* 选项框,指示当前选择的选项 */
LV_PART_ITEMS = 0x050000, /* 相似的元素,例如单元格 */
LV_PART_TICKS = 0x060000, /* 刻度 */
LV_PART_CURSOR = 0x070000, /* 光标 */
};
例如:
void MyGui(void)
{
lv_obj_t * slider = lv_slider_create(lv_scr_act());
lv_obj_set_size(slider, 200, 20);
lv_obj_center(slider);
lv_slider_set_value(slider, 50, LV_ANIM_OFF);
lv_obj_set_style_bg_color(slider, lv_color_hex(0xE0E0E0), LV_PART_MAIN);
lv_obj_set_style_radius(slider, 10, LV_PART_MAIN);
lv_obj_set_style_bg_color(slider, lv_color_hex(0x2196F3), LV_PART_INDICATOR);
lv_obj_set_style_radius(slider, 10, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(slider, lv_color_hex(0xFF5722), LV_PART_KNOB);
lv_obj_set_style_radius(slider, 15, LV_PART_KNOB);
lv_obj_set_style_size(slider, 30, LV_PART_KNOB);
}

API函数:上方示例中出现了一些,此处略
事件
LVGL中,当发生用户感兴趣的事情时,可以触发回调事件,以执行相关的操作,类似于单片机的中断回调函数。这里的回调函数可以检测事件类型以及触发对象。
lv_obj_t * btn;
static void my_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); // 获取事件类型
lv_obj_t * obj = lv_event_get_target(e); // 获取触发对象
if(code == LV_EVENT_CLICKED && obj == btn) LV_LOG_USER("Clicked!");
}
void MyGui(void)
{
btn = lv_btn_create(lv_scr_act());
lv_obj_center(btn);
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL);
}

关于触发,可以有很多种,这里展示一部分(AI搜索)
| 事件 | 触发时机 |
|---|---|
LV_EVENT_PRESSED |
按下(首次接触) |
LV_EVENT_PRESSING |
正在按(持续触发) |
LV_EVENT_PRESS_LOST |
按下后移出对象释放 |
LV_EVENT_SHORT_CLICKED |
短按(按下+释放,无长按) |
LV_EVENT_LONG_PRESSED |
长按达到阈值 |
LV_EVENT_LONG_PRESSED_REPEAT |
长按持续重复触发 |
LV_EVENT_CLICKED |
点击(按下+释放,无移出) |
LV_EVENT_RELEASED |
释放 |
LV_EVENT_SCROLL_BEGIN |
滚动开始 |
LV_EVENT_SCROLL_END |
滚动结束 |
LV_EVENT_SCROLL |
滚动中 |
LV_EVENT_GESTURE |
手势识别(边缘滑动) |
LV_EVENT_KEY |
按键输入 |
LV_EVENT_FOCUSED |
获得焦点 |
LV_EVENT_DEFOCUSED |
失去焦点 |
LV_EVENT_LEAVE |
离开对象(鼠标/触摸移出) |
API函数
添加事件:lv_obj_add_event_cb(obj, event_cb, event_code, user_data);
删除事件:lv_obj_remove_event_cb(obj, event_cb);
部件使用
标签部件(lv_label)
在 LVGL 中,标签部件主要用于文本显示,例如标题、提示信息等。
组成部分:主体(LV_PART_MAIN),滚动条(LV_PART_SCROLLBAR),选中的文本(LV_PART_SELECTED)
设置文本有三种形式
① 直接设置文本,存储文本的内存动态分配 :lv_label_set_text( label, "hallo \n lvgl");
② 文本不存储在动态内存,而是在指定的缓冲区中(慎用):lv_label_set_text_static( label,"hallo" );
③ 格式化显示文本,类似printf :lv_label_set_text_fmt( label, “Value: %d”, 50 ) ;
同样的可以对文本单独设置:
① 背景颜色:lv_obj_set_style_bg_color( label, lv_color_hex(0xffe1d4), LV_STATE_DEFAULT );
② 字体大小:lv_obj_set_style_text_font( label, &lv_font_montserrat_30, LV_STATE_DEFAULT );
③ 文本颜色:lv_obj_set_style_text_color(label, lv_color_hex(0xf7b37b), LV_STATE_DEFAULT );
示例:这里可以设置个别文本的字体颜色
void MyGui(void)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello World!");
lv_obj_center(label);
}
void MyGui(void)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_recolor( label, true );
lv_label_set_text(label, "Hello #ff0000 World!#");
lv_obj_center(label);
}


Q当文本长度超过部件大小的时候怎么显示?
默认情况下,如果没有限定标签部件大小,那它的大小自动扩展为文本大小。
也可以选择长文本模式
enum {
LV_LABEL_LONG_WRAP, /* 默认模式, 如果部件大小已固定,超出的文本将被剪切 */
LV_LABEL_LONG_DOT, /* 将 label 右下角的最后 3 个字符替换为点… */
LV_LABEL_LONG_SCROLL, /* 来回滚动 */
LV_LABEL_LONG_SCROLL_CIRCULAR, /* 循环滚动 */
LV_LABEL_LONG_CLIP, /* 直接剪切掉部件外面的文本部分 */
};
void MyGui(void)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "This is a long piece of text that requires scrolling to be read completely. LVGL provides various long text handling modes.");
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); // 循环滚动
// 必须设置固定宽度,否则不会滚动
lv_obj_set_width(label, 200);
lv_obj_set_height(label, 30);
lv_obj_center(label);
lv_obj_set_style_text_color(label, lv_color_hex(0xffe1d400), 0);
lv_obj_set_style_text_font(label, &lv_font_montserrat_24, 0);
lv_obj_set_style_bg_color(label, lv_color_hex(0x333333), 0);
lv_obj_set_style_bg_opa(label, LV_OPA_COVER, 0);
}
示例效果:正在滚动

按钮部件(lv_btn)
在LVGL中,按钮部件与基础对象相比,没有新增任何功能。
按钮部件组成部分:主体(LV_PART_MAIN)
例程可参考上方事件,一个基础对象可以按下,一个按钮也能按下,倒也区别不大。
static void my_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e); // 获取事件类型
if(code == LV_EVENT_CLICKED) LV_LOG_USER("Clicked!");
else if(code == LV_EVENT_VALUE_CHANGED) LV_LOG_USER("Value changed");
}
void MyGui(void)
{
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_center(btn);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Click Me");
lv_obj_center(label);
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL);
}

开关部件(lv_switch)
开关部件常用于控制某个功能的开启和关闭,它可以直接显示被控对象的状态。
开关部件组成部分:
主体(LV_PART_MAIN)
手柄(LV_PART_KNOB)
指示器(LV_PART_INDICATOR)
示例程序:
static void my_event_cb(lv_event_t * e)
{
lv_obj_t *sw = lv_event_get_target(e); // 获取触发事件的对象
// 获取当前开关的状态 (true = ON, false = OFF)
bool state = lv_obj_has_state(sw, LV_STATE_CHECKED);
if(state)LV_LOG_USER("open\n");
else LV_LOG_USER("close\n");
}
void MyGui(void)
{
lv_obj_t * switch1 = lv_switch_create(lv_scr_act());
lv_obj_center(switch1);
lv_obj_add_event_cb(switch1, my_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}

API:
//创建开关
lv_obj_t *switch1 = lv_switch_create( parent );
//添加、清除开关状态
lv_obj_add_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED); /* 添加状态:默认打开且不可修改 */
lv_obj_clear_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED); /* 清除开关的状态 */
/获取(判断)开关状态
lv_obj_has_state(switch1, LV_STATE_CHECKED) /* 返回值:bool类型,开 :1;关: 0 */
复选框部件(lv_checkbox)
复选框部件常用于选择某个内容的开启和关闭,可以理解为自带标签的开关。
复选框部件组成部分:主体(LV_PART_MAIN) 主体(LV_PART_MAIN)
示例程序:
static void my_event_cb(lv_event_t * e)
{
lv_obj_t *check = lv_event_get_target(e); // 获取触发事件的对象
// 获取当前开关的状态 (true = ON, false = OFF)
bool state = lv_obj_has_state(check, LV_STATE_CHECKED);
if(state)LV_LOG_USER("open\n");
else LV_LOG_USER("close\n");
}
void MyGui(void)
{
lv_obj_t * check1 = lv_checkbox_create(lv_scr_act());
lv_obj_center(check1);
lv_checkbox_set_text(check1, "hello");
lv_obj_add_event_cb(check1, my_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}

API:
//创建复选框部件
lv_obj_t *checkbox = lv_checkbox_create (parent );
//文本设置
lv_checkbox_set_text( checkbox, "remember the password" ); /* 设置文本内容 */
lv_obj_set_style_pad_column( checkbox, 20, LV_STATE_DEFAULT ); /* 设置文本和勾选框的间距 */
//添加、清除复选框状态
lv_obj_add_state(checkbox, LV_STATE_CHECKED | LV_STATE_DISABLED); /* 添加状态:默认选中且不可修改 */
lv_obj_clear_state(checkbox, LV_STATE_CHECKED | LV_STATE_DISABLED); /* 清除复选框的状态 */
//获取(判断)复选框状态
lv_obj_has_state(checkbox, LV_STATE_CHECKED); /* 返回值:1,选中; 0,非选中 */
进度条部件(lv_bar)
进度条部件常用于显示当前任务的完成进度。
进度条部件组成部分:主体(LV_PART_MAIN) 指示器(LV_PART_INDICATOR)
示例程序:
void MyGui(void)
{
lv_obj_t *bar1 = lv_bar_create(lv_scr_act());
lv_obj_center(bar1);
lv_obj_set_style_anim_time(bar1, 500, LV_ANIM_ON);
lv_bar_set_range(bar1, 0, 100);
lv_bar_set_mode(bar1, LV_BAR_MODE_NORMAL);
lv_bar_set_value(bar1, 50, LV_ANIM_ON);
}

一些注意事项(V8.2版本,8.3没测,不过注意一下)
当进度条高度大于宽度时,其方向变为垂直
动画时间设置需要放在当前值设置之前 ,否则看不到动画效果
动画时间指的是旧值刷新到新值的绘图时间,并不是现实中当前值变化所需的时间
API:
//创建显示部件
lv_obj_t *bar = lv_bar_create ( parent );
//设置大小、当前值、范围值
lv_obj_set_size( bar, 400, 20 ); /* 设置大小 */
lv_bar_set_value( bar, 50, LV_ANIM_ON ); /* 设置当前值 */
lv_bar_set_range( bar, -100, 100 ); /* 设置范围值 */
//设置动画时间
lv_obj_set_style_anim_time( bar, 500, LV_STATE_DEFAULT ); /* 动画设置必须放在当前值设置之前 */
另外也可以选装模式:
lv_bar_set_mode( bar, LV_BAR_MODE_RANGE ); /* 设置模式 */
lv_bar_set_start_value( bar, -50, LV_ANIM_OFF ); /* 设置起始值 */
enum {
LV_BAR_MODE_NORMAL, /* 默认模式 */
LV_BAR_MODE_SYMMETRICAL, /* 从零值绘制到当前值(当前值可以小于0) */
LV_BAR_MODE_RANGE /* 允许设置起始值,但起始值必须小于当前值 */
};
加载器部件(lv_spinner)
加载器部件常用于提示当前任务正在加载。
示例程序 一秒转一圈
void MyGui(void)
{
lv_obj_t * spinner1 = lv_spinner_create(lv_scr_act(),1000, 60);//parent,ms,angle
lv_obj_set_style_anim_time(spinner1, 1000, 0);
lv_obj_center(spinner1);
lv_obj_set_style_arc_color(spinner1, lv_color_hex(0x4a9f00), LV_PART_MAIN);
lv_obj_set_style_arc_color(spinner1, lv_color_hex(0xff0000), LV_PART_INDICATOR);
}

API:
//创建加载器部件
lv_obj_t *spinner = lv_spinner_create( parent, spin_time, arc_length );
//设置圆弧颜色
lv_obj_set_style_arc_color( spinner, lv_color_hex(0x4a9f00), LV_PART_MAIN ); /* 设置主体圆弧颜色 */
lv_obj_set_style_arc_color( spinner, lv_color_hex(0x83bd55), LV_PART_INDICATOR ); /* 设置指示器圆弧颜色 */
//设置圆弧宽度
lv_obj_set_style_arc_width( spinner, 30, LV_PART_MAIN ); /* 设置主体圆弧宽度 */
lv_obj_set_style_arc_width( spinner, 30, LV_PART_INDICATOR ); /* 设置指示器圆弧宽度 */
列表部件(lv_list)
列表部件常用于多选一的场景,默认会展现多个选项。
列表部件组成部分:主体(LV_PART_MAIN)滚动条(LV_PART_SCROLLBAR)
示例程序:
void MyGui(void)
{
lv_obj_t *list1 = lv_list_create(lv_scr_act());
lv_obj_set_size(list1, 200, 200);
lv_obj_set_pos(list1, 20, 20);
lv_list_add_text(list1, "setting");
lv_obj_t *btn= lv_list_add_btn( list1, LV_SYMBOL_WIFI, "WLAN");
lv_obj_t *btn1= lv_list_add_btn( list1, LV_SYMBOL_BLUETOOTH, "BLE");
}

在 LVGL v8.3 中,除了 LV_SYMBOL_WIFI,还有大量内置图标可供使用。这些图标基于 FontAwesome 字体库的子集,以宏定义的形式提供。
使用时需要确保对象的字体设置为 LVGL 的内置字体(如 &lv_font_montserrat_16)。
API:
//创建列表部件
lv_obj_t *list = lv_list_create( parent );
//添加列表文本
lv_list_add_text( list, “Settings" );
//添加列表按钮
lv_obj_t *btn= lv_list_add_btn( list, LV_SYMBOL_WIFI, “WLAN");
//获取列表按钮文本
lv_list_get_btn_text( list, list_btn );
滑块部件(lv_slider)
滑块部件常用于调节某个参数的值,它以直线滑动的形式来修改数值。
滑块部件组成部分:
主体(LV_PART_MAIN)
指示器(LV_PART_INDICATOR)
旋钮(LV_PART_KNOB)
有这些模式可以设置:lv_slider_set_mode(slider, LV_SLIDER_MODE_...);


例程:右图
我尝试去掉最外层的蓝色边框,不过似乎并不是部件设置的问题,AI回答说可能LVGL 的默认主题会给处于聚焦状态的控件添加一个蓝色外轮廓(outline),用于指示当前焦点。这个 outline 独立于 bg/border,所以改背景色去不掉
void MyGui(void)
{
lv_obj_t * slider = lv_slider_create(lv_scr_act());
lv_obj_set_size(slider, 200, 15);
lv_obj_center(slider);
lv_slider_set_value(slider, 50, LV_ANIM_OFF);
lv_obj_set_style_bg_color(slider, lv_color_hex(0x808080), LV_PART_MAIN);
lv_obj_set_style_radius(slider, 10, LV_PART_MAIN);
lv_obj_set_style_bg_color(slider, lv_color_hex(0x007AFF), LV_PART_INDICATOR);
lv_obj_set_style_radius(slider, 10, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(slider, lv_color_hex(0xFFFFFF), LV_PART_KNOB);
//手柄边框
lv_obj_set_style_border_width(slider, 2, LV_PART_KNOB);
lv_obj_set_style_border_color(slider, lv_color_hex(0x007AFF), LV_PART_KNOB);
lv_obj_set_style_radius(slider, 15, LV_PART_KNOB);
lv_obj_set_style_size(slider, 10, LV_PART_KNOB);
}
API:
//创建滑块部件
lv_obj_t *slider = lv_slider_create( parent );
//设置大小、当前值、范围值
lv_obj_set_size(slider, 20, 200); /* 高度>宽度时,滑块为纵向 */
lv_slider_set_value(slider, 50, LV_ANIM_OFF); /* 设置当前值 */
lv_slider_set_range(slider, -100, 100); /* 设置范围值 */
//获取当前值
lv_slider_get_value(slider);
//设置、获取左值
lv_slider_set_left_value(slider, 20, LV_ANIM_OFF); /* 设置左值 */
lv_slider_get_left_value(slider); /* 获取左值 */
部件拓展
中文字库
首先要准备需要使用的字体文件(ttf、otf等格式)
登录在线字体转换网站:https://lvgl.io/tools/fontconverter
添加字库文件到LVGL工程中,声明字体,编写测试代码
这里使用鸿蒙字体进行测试:

下载之后改名为.h文件,并添加到CMAKE目录中
另外8.3版本似乎不支持生成文件中的.static_bitmap = 0,,注释掉就好
#include "lvgl/lvgl.h"
#include "mygui.h"
#include "src/temp_16.h"
LV_FONT_DECLARE(temp_16)
void MyGui(void)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "戏舟的嵌入式开源笔记");
lv_obj_center(label);
lv_obj_set_style_text_font(label, &temp_16, 0);
}

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐





所有评论(0)