LVGL—组件介绍

目录

介绍

静态组件

简易显示

基础屏幕(lv_obj_t)

线(lv_line)

条形图(lv_bar)

Led灯(lv_led)

标签(lv_label)

动画显示

基础动画

API

矢量动画(lv_mylottie)

图标类

日历(lv_calendar)

表格(lv_table)

图表(lv_chart)

刻度(lv_scale)

视图类(lv_tabview)

标签视图(lv_tabview)

交互组件

单个交互

开关(lv_switch)

弧形(lv_arc)

消息框(lv_msgbox)

下拉菜单(lv_dropdown)

多个交互

复选框(lv_checkbox)

滚动条(lv_roller)

旋转框(lv_spinbox)

列表(lv_list)

复杂交互

拼音输入法

特殊组件

图片(lv_image)

格式

动图(lv_gif)

特殊模块

添加自定义新字体

观察者

翻译


介绍

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)

和图片一样

特殊模块

添加自定义新字体

官方链接

  1. 找到包含所有简体中文的字体文件
  2. 使用在线字体转换器,转换为LVGL格式的C文件
  3. 在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);

    }

相关推荐
Ashmcracker3 小时前
Codex Desktop如何接入Azure OpenAI?AI Foundry部署GPT‑5.3‑codex 实操
人工智能·gpt·microsoft·azure
公子小六3 小时前
基于.NET的Windows窗体编程之WinForms布局简介
windows·microsoft·c#·.net
weitingfu3 小时前
Excel VBA 入门到精通(一):宏录制与 VBE 环境详解
microsoft
zhengyquan3 小时前
微软砸1.6万亿日元布局日本AI!
人工智能·microsoft
七夜zippoe4 小时前
OpenClaw 消息工具详解:多渠道消息发送实战指南
人工智能·microsoft·多渠道·互动·openclaw
OPHKVPS4 小时前
Ni8mare高危漏洞来袭:黑客可远程劫持n8n服务器(CVE-2026-21858)
人工智能·microsoft
pl4H522a65 小时前
简易的分布式kv设计
windows·qt·microsoft
Darkdreams14 小时前
关于解决Cannot resolve com.microsoft.sqlserversqljdbc44.0报错问题
microsoft
hughnz16 小时前
Palantir Technologies公司的竞争格局
人工智能·microsoft