目录
介绍
LVGL组件大体可以分为三类,静态组件,动态组件,特殊组件
- 静态组件:于人没有交互,只是显示
- 动态组件:于人有交互,人可以进行操作
- 特殊组件:需要外部资源
静态组件
静态组件可分为四类,简易显示,动画显示,图表类,视图类
简易显示
基础屏幕(lv_obj_t)
创建一个最基础的框,UI所有的类容都存放在框里面
//获取当前屏幕 lv_obj_t*scr=lv_screen_active(); //创建一个屏幕 lv_obj_t*scr1=lv_obj_create(scr)
线(lv_line)
就画一条线
//获取当前屏幕 lv_obj_t*scr=lv_screen_active(); //创建一个屏幕 lv_obj_t*scr1=lv_obj_create(scr); //画一条折线 lv_obj_t*line=lv_line_create(scr1); //设置折线经过的点 static lv_point_precise_t points[]={ {5, 5}, {70, 70}, {120, 10}, {180, 60}, {240, 10} }; //参数1:折线 //参数2:折线经过的点 //参数3:折线经过的点个数 lv_line_set_points(line,points,5); //设置线的宽度 lv_obj_set_style_line_width(line,5,LV_PART_MAIN); //设置线的颜色 lv_obj_set_style_line_color(line,lv_palette_main(LV_PALETTE_RED),LV_PART_MAIN); //设置线的圆滑度 lv_obj_set_style_line_rounded(line,true,LV_PART_MAIN);
条形图(lv_bar)
//简单条形图
lv_obj_t * bar1 = lv_bar_create(scr);
//设置条形图大小
lv_obj_set_size(bar1, 200, 20);
//设置位置 center:居中
lv_obj_center(bar1);
//设置条形图的值,
lv_bar_set_value(bar1, 70, LV_ANIM_ON);
Led灯(lv_led)
//简单LED灯
lv_obj_t * led1 = lv_led_create(lv_screen_active());
//设置位置
lv_obj_align(led1, LV_ALIGN_CENTER, -80, 0);
//关闭led
lv_led_off(led1);
lv_obj_t * led2 = lv_led_create(lv_screen_active());
lv_obj_align(led2, LV_ALIGN_CENTER, 0, 0);
//设置亮度
lv_led_set_brightness(led2, 150);
//设置LED颜色
lv_led_set_color(led2, lv_palette_main(LV_PALETTE_RED));
lv_led_on(led2);
lv_obj_t * led3 = lv_led_create(lv_screen_active());
lv_obj_align(led3, LV_ALIGN_CENTER, 80, 0);
//打开led
lv_led_on(led3);
标签(lv_label)
基础功能显示文本
用标签显示符号,通过写入符号对应的字符,从而显示符号,如图2,符号对应字符如图一
#include"staticEasy.h" uint16_t vlaue=0; void but_callback(lv_event_t * e) { //获取按钮对象 lv_obj_t * but = lv_event_get_target(e); //获取按钮的子控件 lv_obj_t *label=lv_obj_get_child(but,0); //按一次加1 vlaue++; //设置标签的文本 lv_label_set_text_fmt(label,"value:%d",vlaue); } void Static_esay_ui_create(void) { //获取当前屏幕 lv_obj_t*scr=lv_screen_active(); //标签 lv_obj_t*but=lv_btn_create(scr); //align:对齐 //lv_align_center:居中 //0,0:x,y偏移量 lv_obj_align(but,LV_ALIGN_CENTER,0,0); lv_obj_set_size(but,160,40); //创建标签 lv_obj_t*label=lv_label_create(but); //显示标签,这里有两种方式显示,非静态(使用动态内存拷贝) //静态(直接到静态内存区获取),这里使用非静态 lv_label_set_text_fmt(label,"value:%d",vlaue); lv_obj_add_event_cb(but,but_callback,LV_EVENT_CLICKED,but); }图一:
图二:
动画显示
基础动画
动画简单,不占用资源
#include "anim.h" //创建动画 static lv_anim_t a; // static lv_anim_t*a1; void label_anim_exec_x(void *obj, int32_t value) { lv_obj_set_x((lv_obj_t*)obj,value); } void but_event_cb(lv_event_t * e) { static uint8_t flag=0; if(flag==0) { lv_anim_set_values(&a,-40,320); lv_anim_start(&a); flag++; } else if(flag==1) { lv_anim_set_values(&a,320,-40); lv_anim_start(&a); flag=0; } } void anim_create(void) { //创建按钮,并居中 lv_obj_t *scr = lv_screen_active(); lv_obj_t *but = lv_button_create(scr); lv_obj_align(but, LV_ALIGN_CENTER, 0, 0); //添加按按钮回调函数 lv_obj_add_event_cb(but, but_event_cb,LV_EVENT_CLICKED,but); //创建标签,并设置位置为0,0 lv_obj_t*label=lv_label_create(scr); lv_obj_set_pos(label,0,0); lv_label_set_text(label,"hello"); //初始化动画 lv_anim_init(&a); //添加控制对象 lv_anim_set_var(&a,label); //设置起始位置 lv_obj_set_x(label,-40); //动画运行时间 lv_anim_set_time(&a,3000); //设置动画起始结束值,0~100 lv_anim_set_values(&a,-40,320); //设置动画回调函数, 这个动画执行回调函数,用于在动画过程中更新对象的 X 坐标位置。 lv_anim_set_exec_cb(&a,label_anim_exec_x); }API
static lv_anim_t a; 声明了一个静态全局的动画变量
初始化动画,将其设置为默认值
lv_anim_init(&a)
添加控制对象
lv_anim_set_var(&a, label);
参数1:动画对象
参数2:控制对象
设置动画起始位置
lv_obj_set_x(label, -40);
lv_obj_set_y(label, -40);
参数1:控制对象
参数2:起始位置
动画运行时间
lv_anim_set_time(&a, 500);
参数1:动画对象
参数2:动画运行时间(ms)
设置动画起始值和结束值,这两个值会传入动画回调函数中
lv_anim_set_values(&a, -40, 140);
参数1:动画对象
参数2:起始值
参数3:结束值
设置动画回调函数, 这个动画执行回调函数,用于在动画过程中更新对象的 X 坐标位置。
lv_anim_set_exec_cb(&a, label_anim_exec_x);
参数1:动画对象
参数2:回调函数
添加反向运行,用于设置动画反向播放的持续时间,(将动画设置为从0~100,再设置反向,动画会先从0运行到100,在从100运行到0)
lv_anim_set_reverse_time(&a, 3000);
参数1:动画对象
参数2:反向回来时间
设置反向延迟,用于设置动画反转(反向播放)前的延迟时间,当动画准备反向时停留的时间
lv_anim_set_reverse_delay(&a, 0);
参数1:动画对象
参数2:延时时间
开始动画
lv_anim_start(&a);
参数1:动画对象
返回值:动画对象指针
删除动画,这删除动画是删除这次运行的动画,并不是将他全删了
lv_anim_delete(a1->var,a1->exec_cb);
参数1:控制对象(通过动画对象指针找)
参数2:回调函数(通过动画对象指针找)
暂停动画
lv_anim_pause(a1);
参数1:动画对象指针
恢复暂停
lv_anim_resume()
参数1:动画对象指针
矢量动画(lv_mylottie)
通过在 动画 这网站找动画,将其下载下来,并获取尺寸,在程序中的获取文件路径中将下载的动画文件地址填进去,并修改渲染尺寸,就能显示该动画
使界面更精美,但占用空间多无实际效果
#include "mylottie.h" void mylottie_create(void) { extern const uint8_t lv_example_lottie_approve[]; extern const size_t lv_example_lottie_approve_size; //创建一个矢量动画 lv_obj_t * lottie = lv_lottie_create(lv_screen_active()); //设置矢量动画的数据源,这种方式获取要python // lv_lottie_set_src_data(lottie, lv_example_lottie_approve, lv_example_lottie_approve_size); //通过文件路径获取动画 //绝对路径 // lv_lottie_set_src_file(lottie, "D:/LVGL/lv_port_pc_vscode-master/lvgl/examples/widgets/lottie/lv_example_lottie_approve.json"); //相对路径 lv_lottie_set_src_file(lottie, "../lvgl/examples/widgets/lottie/lv_example_lottie_approve.json"); //声明了一个静态缓冲区数组,用于存储 Lottie 动画的渲染数据。 static uint8_t buf[64 * 64 * 4]; //为 Lottie 矢量动画设置渲染缓冲区 lv_lottie_set_buffer(lottie, 64, 64, buf); //将动画居中 lv_obj_center(lottie); }
图标类
日历(lv_calendar)
#include "mycalendar.h" void calendar_event_cb(lv_event_t *e) { // 获取当前日历对象的父对象 lv_obj_t *calendar = lv_event_get_current_target(e); // lv_obj_t *calendar = lv_event_get_target(e); // 获取当前选中的日期 static lv_calendar_date_t date; //获取日历上被按下的日期的函数 lv_calendar_get_pressed_date(calendar, &date); printf("calendar_event_cb: %d-%d-%d\n", date.year, date.month, date.day); //将点击的日期高亮 lv_calendar_set_highlighted_dates(calendar, &date, 1); } void calendar_create(void) { lv_obj_t *scr = lv_screen_active(); lv_obj_t *calendar = lv_calendar_create(scr); lv_obj_set_size(calendar, 185, 230); lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0); // 设置日历的今天日期 lv_calendar_set_today_date(calendar, 2026, 3, 26); // 设置显示的月份 lv_calendar_set_month_shown(calendar, 2026, 3); // 添加年月的下拉选择框和箭头 //lv_calendar_add_header_dropdown(calendar); lv_calendar_add_header_arrow(calendar); lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_VALUE_CHANGED, calendar); }
表格(lv_table)
#include "mytable.h"
void table_event_cb(lv_event_t * e)
{
//获取当前表格对象
lv_obj_t * table = lv_event_get_current_target(e);
static uint32_t row, col;
//获取当前选中的单元格的行列号
lv_table_get_selected_cell(table, &row, &col);
printf("table_event_cb: row: %d, col: %d\n", row, col);
//获取当前选中的单元格的用户数据, cell:单元格对象 table:表格对象 row:行号 col:列号
const char *value= lv_table_get_cell_value(table, row, col);
printf("table_event_cb: value: %s\n", value);
}
void mytable_create(void)
{
lv_obj_t * table = lv_table_create(lv_scr_act());
lv_table_set_cell_value(table, 0, 0, "Name");
lv_table_set_cell_value(table, 1, 0, "Apple");
lv_table_set_cell_value(table, 2, 0, "Banana");
lv_table_set_cell_value(table, 3, 0, "Lemon");
lv_table_set_cell_value(table, 4, 0, "Grape");
lv_table_set_cell_value(table, 5, 0, "Melon");
lv_table_set_cell_value(table, 6, 0, "Peach");
lv_table_set_cell_value(table, 7, 0, "Nuts");
lv_table_set_cell_value(table, 0, 1, "Price");
lv_table_set_cell_value(table, 1, 1, "$7");
lv_table_set_cell_value(table, 2, 1, "$4");
lv_table_set_cell_value(table, 3, 1, "$6");
lv_table_set_cell_value(table, 4, 1, "$2");
lv_table_set_cell_value(table, 5, 1, "$5");
lv_table_set_cell_value(table, 6, 1, "$1");
lv_table_set_cell_value(table, 7, 1, "$9");
//设置表格控件的高度。如果内容超出指定高度,表格会显示滚动条
lv_obj_set_height(table, 200);
//将对象在其父容器中居中对齐
lv_obj_center(table);
//创建回调函数
lv_obj_add_event_cb(table, table_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}
图表(lv_chart)
这里系列1和系列2的数组中的数据都一样,但显示出来效果不一样,如图1,因为,两个系列的图标Y轴范围不同,系列1的Y轴范围为100,系列2的范围为200,这里用的折线图,如果要用柱状图,将图表类型改一下就行
#include "mychart.h" void mychart_create(void) { //实现一个简单的折线图(不带刻度) lv_obj_t * chart = lv_chart_create(lv_scr_act()); lv_obj_set_size(chart, 200, 150); //center:将对象在其父容器中居中对齐 lv_obj_center(chart); //设置图表类型为折线图 lv_chart_set_type(chart, LV_CHART_TYPE_LINE); //修改y轴范围 //LV_CHART_AXIS_PRIMARY_Y:主Y轴 //LV_CHART_AXIS_SECONDARY_Y:次Y轴 //axis_range:y轴范围 //0:y轴最小值 100:y轴最大值 lv_chart_set_axis_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 100); lv_chart_set_axis_range(chart, LV_CHART_AXIS_SECONDARY_Y, 0, 200); //创建系列 //series:系列 lv_chart_series_t*series1=lv_chart_add_series(chart,lv_palette_main(LV_PALETTE_RED),LV_CHART_AXIS_PRIMARY_Y); lv_chart_series_t*series2=lv_chart_add_series(chart,lv_palette_main(LV_PALETTE_BLUE),LV_CHART_AXIS_SECONDARY_Y); //设置数据个数,为10个,下面添加数据必须大于10个 lv_chart_set_point_count(chart,10); //添加数据,有两种方法 //获取数组 int32_t *y_array1=lv_chart_get_series_y_array(chart,series1); int32_t *y_array2=lv_chart_get_series_y_array(chart,series2); for (size_t i = 0; i < 10; i++) { //给数组赋值lv_rand(0, 100)随机数 //y_array1[i] = lv_rand(0, 100); // y_array2[i] = lv_rand(0, 100); y_array1[i] = i*10; y_array2[i] = i*10; } //后面有数据更改要刷新图表 lv_chart_refresh(chart); }图一:
刻度(lv_scale)
//实现一个带刻度的12月份的柱状图 //创建屏幕放置图表 lv_obj_t*scr=lv_obj_create(lv_screen_active()); lv_obj_set_size(scr,200,150); lv_obj_center(scr); //再创建一个屏幕使第二级屏幕能够滑动 lv_obj_t*scr2=lv_obj_create(scr); lv_obj_center(scr2); //移除三级屏幕所有样式,当做柱状图的容器 lv_obj_remove_style_all(scr2); //将容器宽度大于二级屏幕这样 lv_obj_set_size(scr2,LV_PCT(300),LV_PCT(100)); //设置容器布局为弹性布局 lv_obj_set_layout(scr2,LV_LAYOUT_FLEX); //设置容器布局方向为列布局 lv_obj_set_flex_flow(scr2,LV_FLEX_FLOW_COLUMN); //创建图表 lv_obj_t*chart=lv_chart_create(scr2); //设置图表宽为100%,这样三级屏幕宽度为100,图表宽度为100, lv_obj_set_width(chart,LV_PCT(100)); //设置对象在 Flexbox 布局中的增长比例 lv_obj_set_flex_grow(chart,1); lv_obj_center(chart); //设置图表类型为柱状图 lv_chart_set_type(chart,LV_CHART_TYPE_BAR); //设置Y轴范围 lv_chart_set_axis_range(chart,LV_CHART_AXIS_PRIMARY_Y,0,100); //创建系列 lv_chart_series_t*series1=lv_chart_add_series(chart,lv_palette_main(LV_PALETTE_RED),LV_CHART_AXIS_PRIMARY_Y); lv_chart_series_t*series2=lv_chart_add_series(chart,lv_palette_main(LV_PALETTE_BLUE),LV_CHART_AXIS_PRIMARY_Y); //设置数据个数 lv_chart_set_point_count(chart,12); //给数组赋值 for (size_t i = 0; i < 12; i++) { lv_chart_set_next_value(chart,series1,lv_rand(0,100)); lv_chart_set_next_value(chart,series2,lv_rand(0,100)); } //刷新图表 lv_chart_refresh(chart); //创建刻度,这里刻度的父容器是三级屏幕,所以刻度会跟随三级屏幕的滚动,不是柱状图 lv_obj_t*scale=lv_scale_create(scr2); //设置刻度模式为正常模式 //LV_SCALE_MODE_HORIZONTAL_TOP: //LV_SCALE_MODE_HORIZONTAL_BOTTOM : //LV_SCALE_MODE_VERTICAL_LEFT //LV_SCALE_MODE_VERTICAL_RIGHT //LV_SCALE_MODE_ROUND_INNER //LV_SCALE_MODE_ROUND_OUTER lv_scale_set_mode(scale,LV_SCALE_MODE_HORIZONTAL_BOTTOM); //设置刻度宽度为100%,高度为25 lv_obj_set_size(scale,LV_PCT(100),25); //设置刻度参数个数 lv_scale_set_total_tick_count(scale,12); //设置刻度主刻度间隔为1,次刻度间隔为0 lv_scale_set_major_tick_every(scale,1); static const char*month_name[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; //设置刻度文本源 lv_scale_set_text_src(scale,month_name); //修改刻度间隔 lv_obj_set_style_pad_hor(scale,lv_chart_get_first_point_center_offset(chart),LV_PART_MAIN);
视图类(lv_tabview)
将多个页面合在一起,通过标签来切换
标签视图(lv_tabview)
#include "mytableview.h"
void my_tableview_create(void)
{
/* 创建一个表格视图 */
lv_obj_t *tableview = lv_tabview_create(lv_screen_active());
// 设置标签页位置和大小
lv_obj_set_pos(tableview, 0, 0);
lv_obj_set_size(tableview, 320, 480);
//创建三个页面
lv_obj_t *tab1 = lv_tabview_add_tab(tableview, "tab1");
lv_obj_t *tab2 = lv_tabview_add_tab(tableview, "tab2");
lv_obj_t *tab3 = lv_tabview_add_tab(tableview, "tab3");
// 设置标签页背景颜色,
lv_obj_set_style_bg_color(tab1, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN);
lv_obj_set_style_bg_color(tab2, lv_palette_main(LV_PALETTE_GREEN), LV_PART_MAIN);
lv_obj_set_style_bg_color(tab3, lv_palette_main(LV_PALETTE_BLUE), LV_PART_MAIN);
//设置背景透明度,要设置完全不透明,默认是透明,透明显示不了标签页颜色
lv_obj_set_style_bg_opa(tab1, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_opa(tab2, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_opa(tab3, LV_OPA_COVER, LV_PART_MAIN);
// 添加一些内容到标签页
lv_obj_t *label1 = lv_label_create(tab1);
lv_label_set_text(label1, "Tab 1 Content");
lv_obj_t *label2 = lv_label_create(tab2);
lv_label_set_text(label2, "Tab 2 Content");
lv_obj_t *label3 = lv_label_create(tab3);
lv_label_set_text(label3, "Tab 3 Content");
// 将标签居中
lv_obj_center(label1);
lv_obj_center(label2);
lv_obj_center(label3);
//设置标签栏位置和大小
lv_tabview_set_tab_bar_position(tableview,LV_DIR_LEFT);
lv_tabview_set_tab_bar_size(tableview,LV_PCT(20));
//修改标签栏位置颜色
//tab:标签页,tab_bar:标签栏
lv_obj_t *tab_bar = lv_tabview_get_tab_bar(tableview);
lv_obj_set_style_bg_color(tab_bar, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
lv_obj_set_style_bg_opa(tab_bar, LV_OPA_COVER, LV_PART_MAIN);
}
交互组件
单个交互
开关(lv_switch)
#include "user_switch.h"
void switch_event_cb(lv_event_t*e)
{
lv_obj_t*sw1=lv_event_get_user_data(e);
//lv_obj_has_state(obj, state)
//检查对象是否处于指定状态
//返回值:1(是)或 0(否)
//LV_STATE_CHECKED 选中/打开状态
//LV_STATE_DEFAULT 默认状态(未选中)
//LV_STATE_PRESSED 按下状态
//LV_STATE_DISABLED 禁用状态
if(lv_obj_has_state(sw1,LV_STATE_CHECKED)==1)
{
printf("2\n");
}
else
{
printf("1\n");
}
}
void user_switch_create(void)
{
//创建一个开关
lv_obj_t*switch1=lv_switch_create(lv_screen_active());
//创建开关回调函数
lv_obj_add_event_cb(switch1,switch_event_cb,LV_EVENT_VALUE_CHANGED,switch1);
}
弧形(lv_arc)
和滑块一样,就是API不同
消息框(lv_msgbox)
void yes_msgbox_event_cb(lv_event_t*e)
{
//这里传进来的e是msgbox
lv_obj_t*msgbox=lv_event_get_user_data(e);
//关闭消息框
lv_msgbox_close_async(msgbox);
printf("yes\n");
}
void no_msgbox_event_cb(lv_event_t*e)
{
//这里传进来的e是msgbox
lv_obj_t*msgbox=lv_event_get_user_data(e);
//关闭消息框
lv_msgbox_close_async(msgbox);
printf("no\n");
}
void user_switch_create(void)
{
lv_obj_t*msgbox=lv_msgbox_create(lv_screen_active());
//设置消息框的标题
//title:标题
lv_msgbox_add_title(msgbox,"hello");
//设置消息框的文本
lv_msgbox_add_text(msgbox,"Hello World");
lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
//添加一个关闭按钮
lv_msgbox_add_close_button(msgbox);
//添加用户选项
lv_obj_t*yes_msgbox=lv_msgbox_add_footer_button(msgbox,"yes");
lv_obj_t*no_msgbox=lv_msgbox_add_footer_button(msgbox,"no");
//LV_EVENT_CLICKED:点击事件
lv_obj_add_event_cb(yes_msgbox,yes_msgbox_event_cb,LV_EVENT_CLICKED,msgbox);
lv_obj_add_event_cb(no_msgbox,no_msgbox_event_cb,LV_EVENT_CLICKED,msgbox);
}
下拉菜单(lv_dropdown)
#include "user_dropdown.h"
void dropdown_event_cb(lv_event_t*e)
{
lv_obj_t*dropdown=lv_event_get_user_data(e);
//获取选中的选项
uint32_t index=lv_dropdown_get_selected(dropdown);
printf("inder:%d\n",index);
}
void user_dropdown_create(void)
{
//创建下拉菜单
lv_obj_t*dropdown=lv_dropdown_create(lv_screen_active());
//添加下拉菜单选项
lv_dropdown_set_options(dropdown, "Apple\n"
"Banana\n"
"Orange\n"
"Cherry\n"
"Grape\n"
"Raspberry\n"
"Melon\n"
"Orange\n"
"Lemon\n"
"Nuts");
//设置下拉菜单展开的不同的方向
//LV_DIR_BOTTOM 下
//LV_DIR_TOP 上
//LV_DIR_LEFT 左
//LV_DIR_RIGHT 右
lv_dropdown_set_dir(dropdown,LV_DIR_RIGHT);
//修改下拉菜单三角符号,匹配下拉菜单展开的方向
//LV_SYMBOL_DOWN 向下
//LV_SYMBOL_UP 向上
//LV_SYMBOL_LEFT 向左
//LV_SYMBOL_RIGHT 向右
lv_dropdown_set_symbol(dropdown,LV_SYMBOL_RIGHT);
lv_obj_add_event_cb(dropdown,dropdown_event_cb,LV_EVENT_VALUE_CHANGED,dropdown);
}
多个交互
复选框(lv_checkbox)
复选框和下拉菜单添加文本信息不一样,复选框和开关差不多,创建一个复选框只能创建一个文本
//复选框 lv_obj_t*scr= lv_obj_create(lv_screen_active()); //将屏幕设置为弹性布局 lv_obj_set_flex_flow(scr,LV_FLEX_FLOW_COLUMN); //创建复选框 lv_obj_t*checkbox=lv_checkbox_create(scr); //添加对应文本 lv_checkbox_set_text(checkbox,"apple"); //将复选框设置为单选模式 //LV_OBJ_FLAG_RADIO_BUTTON:单选模式标志,允许同级对象中只有一个被选中 lv_obj_add_flag(checkbox,LV_OBJ_FLAG_RADIO_BUTTON); lv_obj_t*checkbox1=lv_checkbox_create(scr); lv_checkbox_set_text(checkbox1,"Banana"); lv_obj_add_flag(checkbox1,LV_OBJ_FLAG_RADIO_BUTTON);
滚动条(lv_roller)
和下拉菜单差不太多
旋转框(lv_spinbox)
#include "user_dropdown.h"
void but1_cb(lv_event_t *e)
{
//获取旋转框对象
lv_obj_t*spinbox=lv_event_get_user_data(e);
//调用加函数
lv_spinbox_increment(spinbox);
}
void but2_cb(lv_event_t *e)
{
//获取旋转框对象
lv_obj_t*spinbox=lv_event_get_user_data(e);
//调用减的函数
lv_spinbox_decrement(spinbox);
}
void user_dropdown_create(void)
{
//旋转框
//创建旋转框
lv_obj_t*spinbox=lv_spinbox_create(lv_screen_active());
//设置值的范围,显示5位数0~10000
lv_spinbox_set_range(spinbox,0,10000);
//设置小数点位置,表示3个整数,2个小数
lv_spinbox_set_dec_point_pos(spinbox,3);
//将旋转框设置在中间
lv_obj_center(spinbox);
//获取旋转框高
int32_t h=lv_obj_get_height(spinbox);
//创建两个按钮设置为加减
lv_obj_t*but1=lv_button_create(lv_screen_active());
lv_obj_t*but2=lv_button_create(lv_screen_active());
//将按钮1设置为加号,按钮2设置为减号
//LV_SYMBOL_PLUS:加号
//LV_SYMBOL_MINUS:减号
lv_obj_set_style_bg_img_src(but1,LV_SYMBOL_PLUS,0);
lv_obj_set_style_bg_img_src(but2,LV_SYMBOL_MINUS,0);
//设置按钮位置,大小
lv_obj_set_size(but1,h,h);
lv_obj_set_size(but2,h,h);
//按钮跟着旋转框对齐,
//LV_ALIGN_OUT_LEFT_MID:
//将目标对象放置在参考对象的左侧外部,垂直居中对齐
//对象不会与参考对象重叠,而是紧贴在参考对象左边
//LV_ALIGN_OUT_RIGHT_MID:
//将目标对象放置在参考对象的右侧外部,垂直居中对齐
//对象不会与参考对象重叠,而是紧贴在参考对象右边
lv_obj_align_to(but1,spinbox,LV_ALIGN_OUT_LEFT_MID,0,0);
lv_obj_align_to(but2,spinbox,LV_ALIGN_OUT_RIGHT_MID,0,0);
//添加回调函数实现加减功能
lv_obj_add_event(but1,but1_cb,LV_EVENT_CLICKED,spinbox);
lv_obj_add_event(but2,but2_cb,LV_EVENT_CLICKED,spinbox);
}
列表(lv_list)
效果图

//列表
//创建列表
lv_obj_t*list=lv_list_create(lv_screen_active());
//设置大小和位置
lv_obj_set_size(list,200,200);
lv_obj_center(list);
//添加标题
lv_list_add_text(list,"MYlist");
//添加列表按钮,蓝牙
lv_obj_t*but=lv_list_add_button(list,LV_SYMBOL_BLUETOOTH,"BLUETOOH");
//添加按钮回调函数
lv_obj_add_event_cb(but,but_bluetooth_cb,LV_EVENT_CLICKED,but);
//添加列表按钮,GPS
lv_obj_t*but1=lv_list_add_button(list,LV_SYMBOL_GPS,"GPS");
//添加按钮回调函数
lv_obj_add_event_cb(but1,but_GPS_cb,LV_EVENT_CLICKED,but);
//添加列表按钮,USB
lv_obj_t*but2=lv_list_add_button(list,LV_SYMBOL_USB,"USB");
//添加按钮回调函数
lv_obj_add_event_cb(but2,but_USB_cb,LV_EVENT_CLICKED,but);
复杂交互
拼音输入法
效果展示

#include "user_pinyin.h"
void user_pinyin(void)
{
//创建拼音模型
lv_obj_t*pinyin=lv_ime_pinyin_create(lv_screen_active());
//设置合理字体
lv_obj_set_style_text_font(pinyin,&lv_font_source_han_sans_sc_16_cjk,0);
//设置自定义字典
static const lv_pinyin_dict_t lv_ime_pinyin_def_dict[] = {
{ "a", "啊" },
{ "ai", "爱" },
{ "an", "安暗案" },
{ "ba", "吧把爸八" },
{ "bai", "百白敗" },
{ "ban", "半般辦" },
{ "bang", "旁" },
{NULL,NULL}};
lv_ime_pinyin_set_dict(pinyin,lv_ime_pinyin_def_dict);
//创建文本区域 显示拼音打字
lv_obj_t*textarea=lv_textarea_create(lv_screen_active());
//设置为单行模式
lv_textarea_set_one_line(textarea,true);
//设置合理字体
lv_obj_set_style_text_font(textarea,&lv_font_source_han_sans_sc_16_cjk,0);
//创建一个键盘
lv_obj_t*keyboard=lv_keyboard_create(lv_screen_active());
//设置拼音模块的键盘和文本区域
lv_ime_pinyin_set_keyboard(pinyin,keyboard);
lv_keyboard_set_textarea(keyboard,textarea);
//需改控制板格式
//获取控制板
lv_obj_t*panel=lv_ime_pinyin_get_cand_panel(pinyin);
//设置控制板大小
lv_obj_set_size(panel,LV_PCT(50),LV_PCT(10));
//设置控制板位置
//LV_ALIGN_OUT_TOP_MID:在上方居中
lv_obj_align_to(panel,keyboard,LV_ALIGN_OUT_TOP_MID,0,0);
}
特殊组件
图片(lv_image)
格式
|-----|-----------------------------|
| BMP | 无压缩格式,CPU占用少,直接读取展示,内存占用非常多 |
| PNG | 无损压缩格式,使用时须要对图片格式解压缩,内存小一点 |
| SVG | 矢量格式 |
| JPG | 有损压缩 |
#include "user_image.h"
void user_image_create(void)
{
lv_obj_t * img1 = lv_img_create(lv_screen_active());
//设置文件路径
//在conf.h文件中配置
//(1)如果使用LV_USE_FS_STDIO 1 默认的路径是main.exe
//(2)如果使用LV_USE_FS_WIN32 1 默认的路径是"D:/LVGL/lv_port_pc_vscode-master"
//(3)LV_USE_FS_FATFS 0 这是SD卡的路径,编写默认盘符号=>差SD卡根目录
lv_img_set_src(img1, "B://image.png");
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
}
动图(lv_gif)
和图片一样
特殊模块
添加自定义新字体
- 找到包含所有简体中文的字体文件
- 使用在线字体转换器,转换为LVGL格式的C文件
- 在conf文件添加对应配置
观察者
创建1个主题 subject => 之后添加观察者 主题的值改变会触发观察者回调函数
直接绑定组件,创建主题后,直接将主题与组件绑定,实现双向修改(滑块),滑块可以修改温度参数,修改温度参数也会修改滑块值
#include "user_home.h"
//创建主题
//subject:主题
lv_subject_t temp_subject;//observer:同一个回调函数可以被多个观察者使用,观察者之间通过user_data区分
//subject:被观察的主题,对应被观察的对象
void temp_obs_cb(lv_observer_t * observer, lv_subject_t * subject)
{
//获取上一次值
int32_t prev_value = lv_subject_get_previous_int(subject);
//获取当前值
int32_t value = lv_subject_get_int(subject);
printf("Subject value changed from %d to %d\n", prev_value, value);}
void btn_cb_add(lv_event_t * e)
{
//获取主题
lv_subject_t * subject = lv_event_get_user_data(e);
//修改主题的值
lv_subject_set_int(subject, lv_subject_get_int(subject) + 1);
}void btn_cb_ms(lv_event_t * e)
{
//获取主题
lv_subject_t * subject = lv_event_get_user_data(e);
//修改主题的值
lv_subject_set_int(subject, lv_subject_get_int(subject) - 1);}
void user_home_create(void)
{
//创建标签视图
lv_obj_t*tabview=lv_tabview_create(lv_screen_active());
//设置视图样式 lv_obj_set_size(tabview,LV_PCT(100),LV_PCT(100)); //添加标签页 lv_obj_t*obs_table=lv_tabview_add_tab(tabview,"Obs"); lv_obj_t*obs_table1=lv_tabview_add_tab(tabview,"Obs1"); //添加对应组件到obs页面 //初始化一个主题 => 选择正确的类型和初始值 lv_subject_init_int(&temp_subject, 10); //添加外部参数的观察者,回调函数 ///observer:观察者 lv_subject_add_observer(&temp_subject, temp_obs_cb, NULL); //创建按钮 => 调节温度 lv_obj_t*but_add=lv_btn_create(obs_table); //设置按钮位置和大小 lv_obj_set_size(but_add,50,50); lv_obj_align(but_add,LV_ALIGN_CENTER,-50,0); //添加按钮事件 => 点击时调节温度 lv_obj_add_event_cb(but_add, btn_cb_add, LV_EVENT_CLICKED, &temp_subject); //创建按钮 => 调节温度 lv_obj_t*but_ms=lv_btn_create(obs_table); //设置按钮位置和大小 lv_obj_set_size(but_ms,50,50); lv_obj_align(but_ms,LV_ALIGN_CENTER,50,0); //添加按钮事件 => 点击时调节温度 lv_obj_add_event_cb(but_ms, btn_cb_ms, LV_EVENT_CLICKED, &temp_subject); //创建标签 => 显示加号 lv_obj_t*label_add=lv_label_create(but_add); lv_label_set_text(label_add,LV_SYMBOL_PLUS); lv_obj_center(label_add); //创建标签 => 显示减号 lv_obj_t*label_ms=lv_label_create(but_ms); lv_label_set_text(label_ms,LV_SYMBOL_MINUS); lv_obj_center(label_ms); //创建标签 => 显示温度 lv_obj_t*label_temp=lv_label_create(obs_table); // lv_label_set_text_fmt(label_temp,"Temp: %d", lv_subject_get_int(&temp_subject)); //这样标签显示的值不会随着主题的变化而更新,需要绑定观察者,或者在回调函数中更新标签文本 //绑定观察者 //参数1:标签对象 //参数2:主题 //参数3:格式字符串,%d会被替换为主题的当前值 lv_label_bind_text(label_temp, &temp_subject, "Temp: %d"); lv_obj_align(label_temp,LV_ALIGN_TOP_MID,0,50); //创建滑块 => 实现双向绑定 lv_obj_t*slider=lv_slider_create(obs_table); lv_obj_set_size(slider,200,20); lv_obj_align(slider,LV_ALIGN_BOTTOM_MID,0,-50); //设置滑块范围 => 根据实际需求调整范围 lv_slider_set_range(slider, -100, 100); //绑定观察者 => 滑块值变化时更新主题,主题变化时更新滑块值 lv_slider_bind_value(slider, &temp_subject);}
翻译
在conf.h中开启编译功能
添加3个静态数组 翻译语言:static const char * const languages[] = {"en","chinese", NULL};
要翻译的文字:static const char * const tags[] = {"obs", "translation", NULL};
翻译转化"static const char * const translations[] = {"obs","观察者", "translation","翻译"}
开起静态数组: lv_translation_add_static(languages, tags, translations)
将要翻译的字写在 lv_tr() 中,用双引号
要翻译的字必须是字库中有的
#include "user_home.h"
//创建主题
//subject:主题
lv_subject_t temp_subject;//翻译语言
static const char * const languages[] = {"en","chinese", NULL};
//要翻译的文字
static const char * const tags[] = {"obs", "translation", NULL};
//翻译转化
static const char * const translations[] = {
"obs","观察者",
"translation","翻译"
};//observer:同一个回调函数可以被多个观察者使用,观察者之间通过user_data区分
//subject:被观察的主题,对应被观察的对象
void temp_obs_cb(lv_observer_t * observer, lv_subject_t * subject)
{
//获取上一次值
int32_t prev_value = lv_subject_get_previous_int(subject);
//获取当前值
int32_t value = lv_subject_get_int(subject);
printf("Subject value changed from %d to %d\n", prev_value, value);}
void btn_cb_add(lv_event_t * e)
{
//获取主题
lv_subject_t * subject = lv_event_get_user_data(e);
//修改主题的值
lv_subject_set_int(subject, lv_subject_get_int(subject) + 1);
}void btn_cb_ms(lv_event_t * e)
{
//获取主题
lv_subject_t * subject = lv_event_get_user_data(e);
//修改主题的值
lv_subject_set_int(subject, lv_subject_get_int(subject) - 1);}
void user_home_create(void)
{
//要用翻译功能要开启
//LV_USE_TRANSLATION 1
//开启翻译
lv_translation_add_static(languages, tags, translations);
//设置语言, lv_translation_set_language("chinese"); //创建标签视图 lv_obj_t*tabview=lv_tabview_create(lv_screen_active()); //设置视图样式 lv_obj_set_size(tabview,LV_PCT(100),LV_PCT(100)); //添加标签页 //使用翻译的化要将要翻译的文字用lv_tr()包裹起来 lv_obj_t*obs_table=lv_tabview_add_tab(tabview,lv_tr("obs")); lv_obj_t*translation=lv_tabview_add_tab(tabview,lv_tr("translation")); //添加对应组件到obs页面 //初始化一个主题 => 选择正确的类型和初始值 lv_subject_init_int(&temp_subject, 10); //添加外部参数的观察者,回调函数 ///observer:观察者 lv_subject_add_observer(&temp_subject, temp_obs_cb, NULL); //创建按钮 => 调节温度 lv_obj_t*but_add=lv_btn_create(obs_table); //设置按钮位置和大小 lv_obj_set_size(but_add,50,50); lv_obj_align(but_add,LV_ALIGN_CENTER,-50,0); //添加按钮事件 => 点击时调节温度 lv_obj_add_event_cb(but_add, btn_cb_add, LV_EVENT_CLICKED, &temp_subject); //创建按钮 => 调节温度 lv_obj_t*but_ms=lv_btn_create(obs_table); //设置按钮位置和大小 lv_obj_set_size(but_ms,50,50); lv_obj_align(but_ms,LV_ALIGN_CENTER,50,0); //添加按钮事件 => 点击时调节温度 lv_obj_add_event_cb(but_ms, btn_cb_ms, LV_EVENT_CLICKED, &temp_subject); //创建标签 => 显示加号 lv_obj_t*label_add=lv_label_create(but_add); lv_label_set_text(label_add,LV_SYMBOL_PLUS); lv_obj_center(label_add); //创建标签 => 显示减号 lv_obj_t*label_ms=lv_label_create(but_ms); lv_label_set_text(label_ms,LV_SYMBOL_MINUS); lv_obj_center(label_ms); //创建标签 => 显示温度 lv_obj_t*label_temp=lv_label_create(obs_table); // lv_label_set_text_fmt(label_temp,"Temp: %d", lv_subject_get_int(&temp_subject)); //这样标签显示的值不会随着主题的变化而更新,需要绑定观察者,或者在回调函数中更新标签文本 //绑定观察者 //参数1:标签对象 //参数2:主题 //参数3:格式字符串,%d会被替换为主题的当前值 lv_label_bind_text(label_temp, &temp_subject, "Temp: %d"); lv_obj_align(label_temp,LV_ALIGN_TOP_MID,0,50); //创建滑块 => 实现双向绑定 lv_obj_t*slider=lv_slider_create(obs_table); lv_obj_set_size(slider,200,20); lv_obj_align(slider,LV_ALIGN_BOTTOM_MID,0,-50); //设置滑块范围 => 根据实际需求调整范围 lv_slider_set_range(slider, -100, 100); //绑定观察者 => 滑块值变化时更新主题,主题变化时更新滑块值 lv_slider_bind_value(slider, &temp_subject);}


