概述

本文选用LVGL 8.3版本

8.3版本实测帧率比起9版本高,多个GUI工具支持

相关链接

LVGL官网 https://lvgl.io/

LVGL 文档 https://docs.lvgl.io/8.3/

LVGL仓库 https://github.com/lvgl

LVGL移植

获取源码

https://github.com/lvgl/lvgl/tree/release/v8.3

下载文件即可

image-20250320150540083

文件解析

需要源码中这几个文件

demos 是示例文件

examples 主要是里面的接口文件

src 是源码文件

两个头文件

image-20250320152325529

文件处理

examples

只留下porting一个文件夹

porting 内文件 _template 后缀去掉

image-20250320153554800

image-20250320153711360

lv_conf_template.h去掉 _template

image-20250320154036172

更改后文件

image-20250320154133626

加入文件

将所有src中的c文件加入keil中

我这里分为3个文件组

LVGL_src 存放源码c文件

LVGL_conf存放LVGL设置文件

LVGL_GUI存放自己的GUI文件

image-20250320160736471

脚本加入方法

文件太多了,每个文件夹都要加入比较麻烦

这里使用个python脚本来快速加入

import os

file_lst = []


def print_dir_files(file_path):
    global file_lst
    for file_path, sub_dirs, filenames in os.walk(file_path):
        if filenames:
            # 如果是文件,则加append到list中
            for filename in filenames:
                file_lst.append(os.path.join(file_path, filename))

        for sub_dir in sub_dirs:
            # 如果是目录,则递归调用该函数
            print_dir_files(sub_dir)


if __name__ == '__main__':
    print_dir_files(r"C:\Users\HZ12138\Desktop\LVGL\src")#这里写src文件的绝对目录
    for file_lst_item in file_lst:
        zj = os.path.relpath(file_lst_item, r"C:\Users\HZ12138\Desktop\test")#这里写要相对路径的基位置
        file_name=zj.split("\\")[-1]
        if file_name[-1:]=='c':
            a=r"""
            <File>
              <FileName>"""+file_name+"""</FileName>
              <FileType>1</FileType>
              <FilePath>"""+zj+"""</FilePath>
            </File>
        """
            print(a)

可得到类似这样的内容输出

image-20250320161629077

建议先加入个文件实验下相对路径位置,之后再使用脚本

将MDK文件用文本打开

搜索LVGL_src名称

再文件目录下添加刚才输出的内容即可

image-20250320162522788

image-20250320162628922

image-20250320162640725

配置文件

lvgl.h lvgl_conf.h 还有\examples\porting下的文件加入LVGL_conf

image-20250320163131723

lvgl.h所在目录 src \examples\porting加入头文件目录

image-20250320163720709

image-20250320163558349

Keil设置

打开O3优化和 时间优化 启用c99标准

屏蔽警告(Misc Controls)中加入

--diag_suppress=68,111,188,223,546,1295  --locale=english

image-20250320165606000

Linker 中加入屏蔽警告代码

--diag_suppress=L6314W,L6329W

image-20250320170254851

LVGL模拟器

下载安装

使用VS2022构建LVGL模拟器,VS2022安装请自行解决

模拟器地址

https://github.com/lvgl/lv_port_pc_visual_studio

注意请使用工具从git下克隆指定分支,不要直接下载,直接git克隆会默认最高版本

这里使用 Sourcetree 软件

如下设置,选则版本,选择递归子模块

image-20250320174434444

打开文件运行这个文件即可

image-20250320175040754

image-20250320175105188

更改分辨率

修改 single_display_mode_initialization函数里参数即可

800->长

480->高

image-20250321112336455

LVGL GUI工具

安装

使用 SquareLine Studio 直接从官网下载即可 有免费版本,正常注册即可

https://squareline.io/downloads#lastRelease

建立工程

设置下分辨率 颜色宽度 LVGL版本即可

image-20250321112619508

导出

导出文件

image-20250321112708800

image-20250321112742937

image-20250321112811245

使用

将上述的所有 C H 文件加入

添加ui.h所在的头文件目录

image-20250321112903585

导入ui.h

#include"ui.h"

调用ui_init();即可

LVGL设置

显示驱动移植

lv_port_disp.cstatic void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)

static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
    if (disp_flush_enabled)
    {
        /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

        // int32_t x;
        // int32_t y;
        // for (y = area->y1; y <= area->y2; y++)
        // {
        //     for (x = area->x1; x <= area->x2; x++)
        //     {
        //         /*Put a pixel to the display. For example:*/
        //         /*put_px(x, y, *color_p)*/
        //         color_p++;
        //     }
        // }
        TFT_ST7789_Fill(area->x1, area->y1, area->x2, area->y2, (uint16_t *)color_p);
        HAL_GPIO_TogglePin(LED0_R_GPIO_Port, LED0_R_Pin);
    }

    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

像这样调用

area->x1 x起始坐标
area->y1 y起始坐标
area->x2 x结束坐标
area->y2 y结束坐标
color_p 颜色缓冲区

触摸驱动移植

lv_port_indev.cvoid lv_port_indev_init(void)函数中

打开这部分

    /*------------------
     * Touchpad
     * -----------------*/

    /*Initialize your touchpad if you have*/
    touchpad_init();

    /*Register a touchpad input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    indev_touchpad = lv_indev_drv_register(&indev_drv);

修改接口

/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*Save the pressed coordinates and the state*/
    if (touchpad_is_pressed())
    {
        touchpad_get_xy(&last_x, &last_y);
        data->state = LV_INDEV_STATE_PR;
    }
    else
    {
        data->state = LV_INDEV_STATE_REL;
    }

    /*Set the last pressed coordinates*/
    data->point.x = last_x;
    data->point.y = last_y;
}

/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
    /*Your code comes here*/
    if (FT6236_pressed())
        return true;
    return false;
}

/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t *x, lv_coord_t *y)
{
    /*Your code comes here*/

    uint16_t mx, my;
    FT6236_get_xy(&mx, &my);

    (*x) = my;
    (*y) = 170 - mx;
    // printf("x%d,y%d\n", *x, *y);
}

注意:如果想接入多个触摸设备,可以自行建立多个对应的驱动接口

编码器驱动移植

lv_port_indev.cvoid lv_port_indev_init(void)函数中

打开这部分

    /*------------------
     * Encoder
     * -----------------*/

    /*Initialize your encoder if you have*/
    encoder_init();

    /*Register a encoder input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_ENCODER;
    indev_drv.read_cb = encoder_read;
    indev_encoder = lv_indev_drv_register(&indev_drv);

修改接口

其中data->enc_diff增加和减少意味着编码器滚动,

data->stateLV_INDEV_STATE_RELEASED时则编码器按键未按下,LV_INDEV_STATE_PRESSED则按键已按下

static void encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{

    switch (KEY_Read())
    {
    case 10:
        data->enc_diff++;
        data->state = LV_INDEV_STATE_RELEASED;

        break;
    case 11:
        data->enc_diff--;
        data->state = LV_INDEV_STATE_RELEASED;
        break;
    case 12:
        data->state = LV_INDEV_STATE_PRESSED;

        break;

    default:
        break;
    }
}

设置屏幕大小

lv_port_disp.c文件里定义这两个

#define MY_DISP_HOR_RES 320
#define MY_DISP_VER_RES 170

设置屏幕偏移

lv_port_disp.c文件的void lv_port_disp_init(void)函数中

disp_drv.offset_x = 0;
disp_drv.offset_y = 35;

开调试信息

打开 lv_conf.hLV_USE_PERF_MONITOR以打开FPS和CPU

打开 lv_conf.hLV_USE_MEM_MONITOR以打开内存

控件

通用控件设置

大小设置

可以用于盒子/控件

调用此API即可,详情 大小设置

lv_obj_set_size(obj, w, h);



位置设置

可以用于盒子/控件

坐标系是向右为x正方向,向下为y正方向,如下图,具体的原点可以根据需要设置

image-20251021162951748

设置时会有几个原点选项,代表含义如下图

LV_ALIGN_TOP_LEFT,
LV_ALIGN_TOP_MID,
LV_ALIGN_TOP_RIGHT,
LV_ALIGN_BOTTOM_LEFT,
LV_ALIGN_BOTTOM_MID,
LV_ALIGN_BOTTOM_RIGHT,
LV_ALIGN_LEFT_MID,
LV_ALIGN_RIGHT_MID,
LV_ALIGN_CENTER,

LV_ALIGN_OUT_TOP_LEFT,
LV_ALIGN_OUT_TOP_MID,
LV_ALIGN_OUT_TOP_RIGHT,
LV_ALIGN_OUT_BOTTOM_LEFT,
LV_ALIGN_OUT_BOTTOM_MID,
LV_ALIGN_OUT_BOTTOM_RIGHT,
LV_ALIGN_OUT_LEFT_TOP,
LV_ALIGN_OUT_LEFT_MID,
LV_ALIGN_OUT_LEFT_BOTTOM,
LV_ALIGN_OUT_RIGHT_TOP,
LV_ALIGN_OUT_RIGHT_MID,
LV_ALIGN_OUT_RIGHT_BOTTOM,

image-20251021162445655

指定原点时,会将指定的对象和其父对象的原点均修改

eg1:左上对齐,x偏移0,y偏移0

圆圈为对应的原点位置

详情 对齐

lv_obj_align(obj, LV_ALIGN_TOP_LEFT, 0, 0);

image-20251021210136028image-20251021210405114

eg2:中央对齐,x偏移0,y偏移0

圆圈为对应的原点位置

详情 对齐

lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0);

image-20251021210616687image-20251021210701390

eg2:中央对齐,x偏移30,y偏移0

圆圈为对应的原点位置

详情 对齐

lv_obj_align(temp, LV_ALIGN_CENTER, 30, 0);

image-20251021211343140image-20251021211454753

eg3:中央对齐,x偏移0,y偏移30

圆圈为对应的原点位置

详情 对齐

lv_obj_align(temp, LV_ALIGN_CENTER, 0, -30);

image-20251021212714497image-20251021212654339

字体设置

使用此API来设置字体,设置后对象的字体全部改为 **Font **,这个字体来自导出

lv_obj_set_style_text_font(obj, &Font, LV_STATE_DEFAULT);

使用字体有两种方式,以大数组形式加入工程,以bin文件形式写入指定的存储器(可以是外部flash等)



以大数组形式加入工程

字体使用 **LvglFontTool **软件导出

设置如下图, **6.0版本,XBF内部大数组,字体名Font **

image-20251023215904475

之后将导出的文件加入自己的工程中即可



以bin文件形式写入指定的存储器

设置如下图, **6.0版本,XBF外部bin文件,字体名Font **

image-20251029223740209

之后会得到2个文件,其中Font.bin请自行写入存储器中,注意设置偏移量,Font.c文件加入工程,

image-20251029223831490

设置Font.c中相关读取数据配置,注意设置偏移量

image-20251029224130672

组(lv_group)

用于管理输入信号的,主要是按键/编码器,触摸部分无需使用组

以编码器为例,少量按键建议也当作编码器使用

组有两种模式,编辑模式和普通模式,

在普通模式下,在控件间移动,如下图,可以从一个控件到另一个控件

image-20251023222614151

在编辑模式下,会进入控件内部的选项,这个根据不同控件而改变,例如列表是更改选项,文本框是更改光标位置等等

image-20251023222753556

建议每个页面单独绑定一个组,并在切换页面时将其设为默认组,

如此可以切换页面时不互相影响,同时大多数控件可以自动添加到默认组中

驱动移植 部分详见

移植完成后,会得到一个输入组句柄,lv_indev_t *indev_encoder;

创建组

API详情

group = lv_group_create();

绑定驱动到组

API详情

lv_indev_set_group(indev_encoder, group);

设置为默认组

API详情

lv_group_set_default(group);



对于需要手动调整控件加入或退出组的情况,使用以下

控件添加到组

API详情

lv_group_add_obj(group, obj)

控件从默认组中移除

API详情

lv_group_remove_obj(obj)

修改组编辑模式

API详情

lv_group_set_editing(group, true); //设置为编辑模式

lv_group_set_editing(group, false); //设置为普通模式

基础控制区(盒子)

盒子模型的基础控件,产生一个区域,这个区域可以设定大小,相当于一块画布中的一个窗口,可以产生左右与上下的滚动条

如下图

image-20251020165847205image-20251020165900099

创建

指定好父对象创建即可,默认的obj创建函数即为创建控制区(详情)

lv_obj_t* panel = lv_obj_create(obj);

放置控件

以此控制区为父对象创建即可,下图以标签为例

lv_obj_t* label = lv_label_create(panel);

设置大小,排列位置,以及样式均为通用设置,参考通用控件设置调用即可

注意,lvgl会在内容与盒子模型边缘设置一段空白区来缓冲/隔开

image-20251026214416159

屏幕

屏幕是特殊用法的控制区,也就是一个盒子

可以用于管理各个不同的页面,实现页面的切换功能

创建屏幕

父对象指定为NULL创建盒子即可(详情 创建盒子)

screen = lv_obj_create(NULL);

放置对象

以此屏幕为父对象创建即可,下图以标签为例

lv_obj_t* label = lv_label_create(screen);

加载到屏幕

调用此函数后便会加载到指定屏幕(详情 加载到屏幕)

lv_disp_load_scr(screen);

布局(layout)

网格布局(Grid)

使用后可以将盒子修改为网格布局,内部会存在ui上隐藏的网格,每行(row)和每列(col)的宽度均可单独设置,类似表格,可以灵活布局

仅用于布局,其他特性与普通盒子相同

注意:设置好所有的行列宽度后,并不会将内部空间的大小设置为总网格大小,而是会根据控件来计算

如下图,虚线是网格总大小,红色是一个控件,而实线则是盒子内部空间的大小,具体显示的范围要根据设置而定

image-20251022145749149

创建

首先创建两个数组,用来存储每行/每列的像素,数组最后要以LV_GRID_TEMPLATE_LAST结尾,数组要设为静态/全局变量 渲染UI时需要调用这部分数据,

之后将上述用到的数组绑定到盒子中,并设置为网格模式(LV_LAYOUT_GRID)即可

详情 网格绑定行列

详情 设置布局模式

static lv_coord_t col_dsc[] = { 1, LV_GRID_TEMPLATE_LAST };
static lv_coord_t row_dsc[] = { 1, LV_GRID_TEMPLATE_LAST };
    
lv_obj_set_grid_dsc_array(panel, col_dsc, row_dsc);
lv_obj_set_layout(panel, LV_LAYOUT_GRID);


static lv_style_t style_panel;
lv_style_init(&style_panel);
lv_style_set_pad_column(&style_panel, 0);//列间间隔0
lv_style_set_pad_row(&style_panel, 0);//行间间隔0
lv_obj_add_style(panel, &style_panel, 0);

放置到网格中

绘制方向依旧按照,右+,下+的约定,

image-20251021162951748

align参数

设置为LV_GRID_ALIGN_START即是对齐开始绘制的方向

对于 **行(row) **来说就是 **左对齐 **(因为格子是向x+方向绘制,格子的左侧先绘制)

对于 **列(col) **来说就是 **上(顶)对齐 **(因为格子是向y+方向绘制,格子的上侧先绘制)


设置为LV_GRID_ALIGN_CENTER即是对齐中心

对于 **行(row) **来说就是 **左右居中对齐 **

对于 **列(col) **来说就是 **上下居中对齐 **


设置为LV_GRID_ALIGN_END即是对齐结束绘制的方向

对于 **行(row) **来说就是 **右对齐 **(因为格子是向x+方向绘制,格子的左侧先绘制)

对于 **列(col) **来说就是 **下(底)对齐 **(因为格子是向y+方向绘制,格子的上侧先绘制)


设置为LV_GRID_ALIGN_STRETCH是将对象的 宽/高 扩展到格子在这个方向的大小

对于 **行(row) **来说就是 **对象宽度 **变为格子大小

对于 **列(col) **来说就是 **对象高度 **变为格子大小


span参数

此对象占据行/列的数量,至少为1

eg:各设为2,则占据2X2=4格的矩形区域


注意,下方的示例均为3X3的格子,格子像素为100px,对象为TEXT 32px高文本框,底色改为黑色

eg1:起始 **(0,0) **, **列 **占用 **2 **格, **列方向(x) 扩展到单元格大小 **, **行 **占用1格, **行方向(y) 居中方向对齐 **

详情 设置网格与对齐

lv_obj_set_grid_cell(obj,
                     LV_GRID_ALIGN_STRETCH, 0, 2,
                     LV_GRID_ALIGN_CENTER, 0, 1);

image-20251022201910820image-20251022204024354

eg2:起始 **(0,0) **, **列 **占用 **1 **格, **列方向(x) 扩展到单元格大小 **, **行 **占用1格, **行方向(y) 扩展到单元格大小 **

详情 设置网格与对齐

lv_obj_set_grid_cell(obj, 
                     LV_GRID_ALIGN_STRETCH, 0, 1,
                     LV_GRID_ALIGN_STRETCH, 0, 1);

image-20251022202022770image-20251022202719366

eg3:起始 **(0,0) **, **列 **占用 **1 **格, **列方向(x) 按终止方向对齐 **, **行 **占用1格, **行方向(y) 起始方向对齐 **

详情 设置网格与对齐

lv_obj_set_grid_cell(obj,
                     LV_GRID_ALIGN_END, 0, 1,
                     LV_GRID_ALIGN_START, 0, 1);

image-20251022202339053image-20251022204135936

eg4:起始 **(0,0) **, **列 **占用 **1 **格, **列方向(x) 起始方向对齐 **, **行 **占用1格, **行方向(y) 按终止方向对齐 **

详情 设置网格与对齐

lv_obj_set_grid_cell(temp,
                     LV_GRID_ALIGN_START, 0, 1,
                     LV_GRID_ALIGN_END, 0, 1);

image-20251022204305620image-20251022204324399

样式(styles)

可以给各个控件设置样式

基础使用

先创建(lv_style_init)样式,要设置为静态/全局变量,ui渲染时会使用,要求全生命周期,API详情

再将根据需要设置样式

之后给控件添加样式,API详情

static lv_style_t style;
lv_style_init(&style);
/*根据需要设置样式*/
lv_obj_add_style(obj, &style, 0);

设置盒子的内边距

即图中的的Padding,API详情

image-20251026221030511

lv_style_set_pad_all(&style, value);//上下左右边框

lv_style_set_pad_left(&style, value);//左边框
lv_style_set_pad_right(&style, value);//右边框
lv_style_set_pad_top(&style, value);//上边框
lv_style_set_pad_bottom(&style, value);//下边框

设置网格布局行/列间间距

网格布局详情

API详情

lv_style_set_pad_column(&style, 0);//列间间隔0
lv_style_set_pad_row(&style, 0);//行间间隔0

设置圆角半径

可以给控件添加圆角,会添加到四个角上

可以设置为LV_RADIUS_CIRCLE,以将控件变为圆形,API详情

lv_style_set_radius(&style, 0);

标签(lv_label)

用于显示文本的控件

创建

使用 标签创建函数来创建标签

lv_obj_t* label;

label = lv_label_create(parent);

设置大小

文本框默认大小是刚刚能包裹设置的文字,与文字内容和字体高度有关

设置大小后如果文字内容超过设置的宽度,则会截断

API详情

lv_obj_set_size(label, w, h);

设置字体

对于标签来说写默认LV_STATE_DEFAULT即可

API详情

lv_obj_set_style_text_font(label, &Font, LV_STATE_DEFAULT);

设置文本

这个函数不需要保留缓冲区(text),lvgl会创建新的缓冲区来存放文本

API详情

lv_label_set_text(label, text);

设置位置

通用设置中的设置位置 详情

lv_obj_align(label, LV_ALIGN_TOP_LEFT, x, y);

设置字体排列

此函数只能设置为左右居中(设置了宽高的情况下)

API详情

lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, LV_STATE_DEFAULT);

设置上下居中(设置了宽高的情况下),参考以下代码

h是标签高度,Font是字体变量

((lv_label_t*)label)->offset.y = (h - Font.line_height) / 2;
lv_obj_set_size(label, w, h);


封装的一个常用设置标签的函数,

其中Font为自己的字体,

默认文本 左右上下居中 放置

lv_obj_t* ui_create_label(lv_obj_t* parent, 
                          lv_coord_t w, lv_coord_t h, 
                          lv_coord_t x, lv_coord_t y, 
                          const char* text)
{
    lv_obj_t* label;
    
    label = lv_label_create(parent);
    lv_obj_set_style_text_font(label, &Font, LV_STATE_DEFAULT); // 设置字体
    lv_label_set_text(label, text);
    lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, LV_STATE_DEFAULT);//左右居中

    if (w * h != 0)
    {
        lv_obj_set_size(label, w, h);
        ((lv_label_t*)label)->offset.y = (h - Font.line_height) / 2;
        
    }
    lv_obj_align(label, LV_ALIGN_TOP_LEFT, x, y);
    return label;
}
名称 类型 描述
parent lv_obj_t * 父对象
w lv_coord_t 宽度(可写0)
h lv_coord_t 高度(可写0)
x lv_coord_t x位置(可写0)
y lv_coord_t y位置(可写0)
const char* text 文本
返回 lv_obj_t * 建立的对象指针

按钮(lv_button)

按钮是常用的控件,默认样式如下

组相关:按钮会被放入默认组中

image-20251023114344818

创建

API详情

lv_obj_t* btn;
btn = lv_btn_create(father);

设置位置和大小,指定样式

通用设置中的设置位置 详情

同时也可指定样式 详情

lv_obj_set_size(btn, w, h);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x, y);

lv_obj_add_style(btn, style_btn, LV_STATE_DEFAULT);

放置并修改文字

以按钮为父对象内部建立一个标签即可

详情

lv_obj_t *label;
label = lv_label_create(btn);
lv_obj_set_style_text_font(label, &Font, LV_STATE_DEFAULT); 
lv_label_set_text(label, text);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

封装一个快速创建按钮的函数

样式可传入NULL使用默认样式

lv_obj_t *ui_create_btn(lv_obj_t *father,
                        lv_coord_t w, lv_coord_t h,
                        lv_coord_t x, lv_coord_t y,
                        const char *text, lv_style_t *style_btn,
                        lv_obj_t  **plabel)
{


    lv_obj_t *btn = lv_btn_create(father);
    lv_obj_set_size(btn, w, h);
    lv_obj_set_pos(btn, x, y);
    if (style_btn != NULL)
        lv_obj_add_style(btn, style_btn, 0);

    lv_obj_t *label;
    label = lv_label_create(btn);
    lv_obj_set_style_text_font(label, &Font, LV_STATE_DEFAULT); // 设置字体
    
    lv_label_set_text(label, text);
    lv_obj_center(label);

    if (plabel != NULL)
        *plabel = label;
    return btn;
}
名称 类型 描述
parent lv_obj_t * 父对象
w lv_coord_t 宽度(u16/u32)
h lv_coord_t 高度(u16/u32)
x lv_coord_t x位置(u16/u32)
y lv_coord_t y位置(u16/u32)
text const char* 文字缓冲区(无需全生命周期)
style_btn lv_style_t* 按钮样式(可写NULL以默认样式)
plabel lv_obj_t* 按钮的标签指针
返回 lv_obj_t * 建立的对象(按钮)指针

设置回调函数

给按钮添加事件,对于按钮来说一般设为点击时触发

在触发时会自动调用btn_cb函数

注意,btn_id不需要全生命周期,仅使用了数值,使用后可以修改供其他回调函数使用

API详情

int btn_id=0;
lv_obj_add_event_cb(obj, btn_cb, LV_EVENT_CLICKED, (void *)btn_id);
void btn_cb(lv_event_t *e)
{
    int btn_id = (int)lv_event_get_user_data(e);// 获取用户数据
    
    // lv_event_code_t code = lv_event_get_code(e);  // 获取事件类型
    // lv_obj_t *obj = lv_event_get_target(e);       // 获取触发事件的对象
}

列表(lv_list)

列表可以添加两种子控件,文本和按钮,可以上下滑动

可设定大小,当内部子控件数量超过范围时会出现滚动条

组相关:文本不可以被选中,按钮可以选中,当选中最后一个按钮时,下一个控件将会跳转到第一个按钮,按钮均被放入默认组中

image-20251023203039580

创建

API 详情

lv_obj_t *list;
list = lv_list_create(parent);  

设置大小,位置,字体

通用设置中的相关位置 详情

lv_obj_set_size(list, w, h);
lv_obj_align(list, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_text_font(list, &Font, LV_STATE_DEFAULT);

添加子控件

创建后可以返回控制子控件的指针

**文本 **控件与 **标签(lv_label) **相同,详见,API参考

**按钮 **控件与 **按钮(lv_button) **相同,详见,API参考

lv_obj_t *list_label , *list_btn;

list_label = lv_list_add_text(list, "TEXT");

list_btn = lv_list_add_btn(list, "", "BTN");

同样可以给按钮设置回调函数,当点击时触发

int btn_id=0;
lv_obj_add_event_cb(list_btn, btn_cb, LV_EVENT_CLICKED, (void *)btn_id);
void btn_cb(lv_event_t *e)
{
    int btn_id = (int)lv_event_get_user_data(e);// 获取用户数据\
    
    // lv_event_code_t code = lv_event_get_code(e);  // 获取事件类型
    // lv_obj_t *obj = lv_event_get_target(e);       // 获取触发事件的对象
}

文本框(lv_textarea)

一般用于需要编辑的文本,如输入的信息(账号/密码)等

可以配合键盘使用写入文本

image-20251024203617275

创建

API详情

lv_obj_t* textarea;
textarea = lv_textarea_create(parent);

设置大小,位置,字体

通用设置中的相关位置 详情

lv_obj_set_size(textarea, w, h);
lv_obj_align(textarea, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_text_font(textarea, &Font, LV_STATE_DEFAULT);

文本相关

设置文本,会将原有内容清空,API详情

lv_textarea_set_text(textarea, "TEXT");

插入文本,会向光标文字插入指定的文本,API详情

lv_textarea_add_text(textarea, "TEXT");

删除光标前侧字符,类似电脑的back键,API详情

lv_textarea_del_char(textarea);

删除光标后侧字符,类似电脑的Del键,API详情

lv_textarea_del_char_forward(textarea);

光标操作

设置光标位置

如下,文本为text,则t的前方为0位置,t和e之间为1位置,以此类推,

可以设置为LV_TEXTAREA_CURSOR_LAST将光标移到末尾.API详情

t e x t
0 1 2 3 4
-4 -3 -2 -1
lv_textarea_set_cursor_pos(textarea, 0);

光标向上/下/左/右移动光标.API详情

lv_textarea_cursor_up(textarea);
lv_textarea_cursor_down(textarea);
lv_textarea_cursor_left(textarea);
lv_textarea_cursor_right(textarea);

设置占位文字

会在没有输入/设置文本时显示的内容,API详情

lv_textarea_set_placeholder_text(textarea, "TEXT");

image-20251024212652061

设置单行模式

当文本内容超过宽度时,如果未设置(false)单行模式,则会换行并在超过高度时出现竖向滑动条

image-20251024221625837

当文本内容超过宽度时,如果设置(true)单行模式,则会出现横向的滑动条,API详情

image-20251024221921135

lv_textarea_set_one_line(textarea, true);

文本白名单

仅在名单中的字符会被加入文本框中,如下为仅使用数字,API详情

lv_textarea_set_accepted_chars(textarea, "0123456789");

文本最大长度

超过设定值后输入的内容无效,不会加入文本框,API详情

lv_textarea_set_max_length(textarea, 8);

密码模式

可以让输入的字符变为 * ,如同手机上输入密码一样,API详情

image-20251024223351811

lv_textarea_set_password_mode(textarea, true);

获取文本框内容

API详情

char * data;
data = lv_textarea_get_text(textarea);

常用事件

设置事件回调,API详情

lv_obj_add_event_cb(textarea, textarea_event_handler, LV_EVENT_READY, NULL);
void textarea_event_handler(lv_event_t * e)
{
    lv_obj_t *obj = lv_event_get_target(e);       // 获取触发事件的对象
}
名称 触发时机
LV_EVENT_VALUE_CHANGED 内容改变时触发
LV_EVENT_READY 接收到enter键时触发

注意:只有当文本框处于聚焦(LV_STATE_FOCUSED )时光标会出现

触摸或用按键选中文本框时会进入聚焦模式,显示光标

键盘(lv_keyboard)

一般用于往文本框等控件中写入文字,如下图

image-20251025171720719

创建

API详情

lv_obj_t* kb;
kb = lv_keyboard_create(parent)

关联键盘到文本框

关联后键盘输入的内容会输入到文本框(相当于指针位置插入字符,即调用此API)

文本框详情

API详情

lv_keyboard_set_textarea(kb, textarea);

设置键盘模式

26键英文小写键盘模式 LV_KEYBOARD_MODE_TEXT_LOWER

image-20251025211006832

26键英文大写键盘模式 LV_KEYBOARD_MODE_TEXT_UPPER (默认)

image-20251025211027805

数字键盘模式 LV_KEYBOARD_MODE_NUMBER

image-20251025211052319

API详情

lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_UPPER);

常用事件

设置事件回调,API详情

lv_obj_add_event_cb(kb, kb_event_handler, LV_EVENT_READY, NULL);
void kb_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);  // 获取事件类型
    
    // lv_event_get_user_data(e);// 获取用户数据
    // lv_obj_t *obj = lv_event_get_target(e);       // 获取触发事件的对象
}
名称 触发时机
LV_EVENT_READY 按下确定(1)键时
LV_EVENT_CANCEL 按下关闭(2)键时

image-20251025212631768

编码器模式下,会出现聚焦到键盘时,文本框焦点消失问题

可以手动将键盘设置为编辑模式,同时聚焦文本

编辑模式API详情

聚焦(状态设置)API详情

lv_group_set_editing(group, true);
lv_obj_add_state(textarea, LV_STATE_FOCUSED);

选择框(lv_checkbox)

默认的选择框是复选框,类似这种

image-20251025220020053

创建

创建的时候会创建单独复选框,建议将其放到一个单独的盒子中

API详情

lv_obj_t *checkbox;
checkbox = lv_obj_create(parent);


lv_obj_t *checkbox_btn;
checkbox_btn = lv_checkbox_create(checkbox);

设置文本

API详情

lv_checkbox_set_text(checkbox_btn, txt);

设置大小,位置,字体,样式

通用设置中的相关位置 详情

lv_obj_set_size(checkbox, w, h);
lv_obj_align(checkbox, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_text_font(checkbox, &Font, LV_STATE_DEFAULT);

事件回调

设置事件回调,API详情

lv_obj_add_event_cb(radio_btn, checkbox_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
void checkbox_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);  // 获取事件类型
    
    // lv_event_get_user_data(e);// 获取用户数据
    // lv_obj_t *obj = lv_event_get_target(e);       // 获取触发事件的对象
}
名称 描述
LV_EVENT_FOCUSED 焦点到选择框时
LV_EVENT_CLICKED 按下选择框时

状态说明

单选框实现

单选框需要自己实现,lvgl没有相关集成控件

基本上需要做的是 修改样式(改为圆形等),在点击时清除已经选择的选择框并同时将点击的选择框选中

首先建立几个全局变量

具体使用的API请自行搜索本文

lv_style_t style_radio, style_radio_chk;//样式
uint32_t radio_index = 0;//存储当前选中的编号
lv_obj_t *radio_box; // 单选框句柄
/ **
 * @brief 单选框回调
 * @param e 事件
 * @author HZ12138
 * @date 2025-09-30 16:13:41
 */
void radio_btn_foused_cb(lv_event_t *e)
{
    uint32_t *active_id = (uint32_t *)lv_event_get_user_data(e);//获取 存储当前编号 的指针
    lv_obj_t *cont = lv_event_get_current_target(e);//当前的激活对象
    lv_obj_t *act_cb = lv_event_get_target(e);//最初目标即当前被激活的 选择子框
    lv_obj_t *old_cb = lv_obj_get_child(cont, *active_id);//之前选中的 选择子框


    // 单选框实现
    
    //因为调用回调时将选择子框的事件传递到了整个选择框(盒子),会触发此函数多次,当由选择框(盒子)触发时,什么都不做
    if (act_cb == cont)
        return;
    lv_obj_clear_state(old_cb, LV_STATE_CHECKED); // 将旧选择项清除
    lv_obj_add_state(act_cb, LV_STATE_CHECKED);   // 并将新选择项置位

    *active_id = lv_obj_get_index(act_cb);//设置新的编号
}
/ **
 * @brief 圆选项卡创建
 * @param parent 父对象
 * @param txt 文本
 * @author HZ12138
 * @date 2025-09-30 16:12:39
 */
void radiobutton_create(lv_obj_t *parent, const char *txt)
{
    lv_obj_t *obj = lv_checkbox_create(parent);//创建选择子框
    lv_checkbox_set_text(obj, txt);//设置文本
    
    lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);//将选择子框的事件传递到 选择框(盒子中)
    lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);//将选择的方框设为圆形
    lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);//清除选中时的背景
}

设置样式

lv_style_init(&style_radio);
lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);//将选择的方框设为圆形

lv_style_init(&style_radio_chk);
lv_style_set_bg_img_src(&style_radio_chk, NULL);//清除选中时的背景
radio_box = lv_obj_create(screen_FunSel); 
lv_obj_add_event_cb(radio_box, radio_btn_foused_cb, LV_EVENT_CLICKED, &radio_index); // 设置回调和选择元素id的句柄
radiobutton_create(radio_box, TEXT);

单选框 用于编码器模式的优化

lv_obj_add_event_cb(radio_box, radio_btn_foused_cb, LV_EVENT_FOCUSED, &radio_index); // 设置回调和选择元素id的句柄

改变触发时机,当框选到时即选中选择子框,以简化操作

radio_btn_foused_cb函数中在进入编辑模式时退出

lv_style_t style_radio, style_radio_chk;//样式
uint32_t radio_index = 0;//存储当前选中的编号
lv_obj_t *radio_box; // 单选框句柄
/ **
 * @brief 单选框回调
 * @param e 事件
 * @author HZ12138
 * @date 2025-09-30 16:13:41
 */
void radio_btn_foused_cb(lv_event_t *e)
{
    uint32_t *active_id = (uint32_t *)lv_event_get_user_data(e);//获取 存储当前编号 的指针
    lv_obj_t *cont = lv_event_get_current_target(e);//当前的激活对象
    lv_obj_t *act_cb = lv_event_get_target(e);//最初目标即当前被激活的 选择子框
    lv_obj_t *old_cb = lv_obj_get_child(cont, *active_id);//之前选中的 选择子框

    lv_group_set_editing(group, false); // 禁止编辑

    // 单选框实现
    
    //因为调用回调时将选择子框的事件传递到了整个选择框(盒子),会触发此函数多次,当由选择框(盒子)触发时,什么都不做
    if (act_cb == cont)
        return;
    lv_obj_clear_state(old_cb, LV_STATE_CHECKED); // 将旧选择项清除
    lv_obj_add_state(act_cb, LV_STATE_CHECKED);   // 并将新选择项置位

    *active_id = lv_obj_get_index(act_cb);//设置新的编号
}
/ **
 * @brief 圆选项卡创建
 * @param parent 父对象
 * @param txt 文本
 * @author HZ12138
 * @date 2025-09-30 16:12:39
 */
void radiobutton_create(lv_obj_t *parent, const char *txt)
{
    lv_obj_t *obj = lv_checkbox_create(parent);//创建选择子框
    lv_checkbox_set_text(obj, txt);//设置文本
    
    lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);//将选择子框的事件传递到 选择框(盒子中)
    lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);//将选择的方框设为圆形
    lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);//清除选中时的背景
}

lv_style_init(&style_radio);
lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);//将选择的方框设为圆形

lv_style_init(&style_radio_chk);
lv_style_set_bg_img_src(&style_radio_chk, NULL);//清除选中时的背景
radio_box = lv_obj_create(screen_FunSel); 
lv_obj_add_event_cb(radio_box, radio_btn_foused_cb, LV_EVENT_FOCUSED, &radio_index); // 设置回调和选择元素id的句柄
radiobutton_create(radio_box, TEXT);

APIs

创建盒子

lv_obj_t * lv_obj_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

加载到屏幕

void lv_disp_load_scr(lv_obj_t * scr)
名称 类型 描述
scr lv_obj_t * 屏幕
返回 void

大小设置

void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
w lv_coord_t 宽度(u16(默认)/u32)
h lv_coord_t 高度(u16(默认)/u32)
返回 void

对齐

void lv_obj_align(struct _lv_obj_t * obj, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
align lv_align_t 原点(可为下表中其一)
x_ofs lv_coord_t x偏移,+右-左(u16(默认)/u32)
y_ofs lv_coord_t y偏移,+下-上(u16(默认)/u32)
返回 void
enum {
    LV_ALIGN_DEFAULT = 0,
    LV_ALIGN_TOP_LEFT,
    LV_ALIGN_TOP_MID,
    LV_ALIGN_TOP_RIGHT,
    LV_ALIGN_BOTTOM_LEFT,
    LV_ALIGN_BOTTOM_MID,
    LV_ALIGN_BOTTOM_RIGHT,
    LV_ALIGN_LEFT_MID,
    LV_ALIGN_RIGHT_MID,
    LV_ALIGN_CENTER,

    LV_ALIGN_OUT_TOP_LEFT,
    LV_ALIGN_OUT_TOP_MID,
    LV_ALIGN_OUT_TOP_RIGHT,
    LV_ALIGN_OUT_BOTTOM_LEFT,
    LV_ALIGN_OUT_BOTTOM_MID,
    LV_ALIGN_OUT_BOTTOM_RIGHT,
    LV_ALIGN_OUT_LEFT_TOP,
    LV_ALIGN_OUT_LEFT_MID,
    LV_ALIGN_OUT_LEFT_BOTTOM,
    LV_ALIGN_OUT_RIGHT_TOP,
    LV_ALIGN_OUT_RIGHT_MID,
    LV_ALIGN_OUT_RIGHT_BOTTOM,
};

网格绑定行列

void lv_obj_set_grid_dsc_array(lv_obj_t * obj, const lv_coord_t col_dsc[], const lv_coord_t row_dsc[])
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
col_dsc const lv_coord_t 列宽度数组(设为静态变量)
row_dsc const lv_coord_t 行宽度数组(设为静态变量)
返回 void

注意:两个数组要设为静态变量或全局变量,再UI渲染时需要调用此数据

设置布局模式

void lv_obj_set_layout(struct _lv_obj_t * obj, uint32_t layout);
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
layout uint32_t 布局选项(可为下表其一)
返回 void
LV_LAYOUT_GRID
LV_LAYOUT_FLEX

设置网格与对齐

void lv_obj_set_grid_cell(lv_obj_t * obj, lv_grid_align_t x_align, uint8_t col_pos, uint8_t col_span,
                          lv_grid_align_t y_align, uint8_t row_pos, uint8_t row_span)
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
x_align lv_grid_align_t x方向对齐
col_pos uint8_t 占用列坐标
col_span uint8_t 占用列数
y_align lv_grid_align_t y方向对齐
row_pos uint8_t 占用行坐标
row_span uint8_t 占用行数
返回 void
typedef enum {
    LV_GRID_ALIGN_START,
    LV_GRID_ALIGN_CENTER,
    LV_GRID_ALIGN_END,
    LV_GRID_ALIGN_STRETCH,
    LV_GRID_ALIGN_SPACE_EVENLY,
    LV_GRID_ALIGN_SPACE_AROUND,
    LV_GRID_ALIGN_SPACE_BETWEEN,
} lv_grid_align_t;

标签创建

lv_obj_t * lv_label_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

设置字体

void lv_obj_set_style_text_font(struct _lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector)
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
value const lv_font_t * 字体
selector lv_style_selector_t 何时使用(可为以下)
返回 void
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,

    LV_STATE_USER_1      =  0x1000,
    LV_STATE_USER_2      =  0x2000,
    LV_STATE_USER_3      =  0x4000,
    LV_STATE_USER_4      =  0x8000,

    LV_STATE_ANY = 0xFFFF, 
};

标签文本设置

void lv_label_set_text(lv_obj_t * obj, const char * text)
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
text const char * 文本
返回 void

这将动态分配一个缓冲区,并且提供的字符串将被复制到该缓冲区中。 因此,在该函数返回后,不需要将传递给 lv_label_set_text 的文本保留在作用域中

样式字体排列设置

void lv_obj_set_style_text_align(struct _lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector)
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
value lv_text_align_t 排列选项(可为表1)
selector lv_style_selector_t 何时使用(可为表2)
返回 void
enum {
    LV_TEXT_ALIGN_AUTO, / **< Align text auto*/
    LV_TEXT_ALIGN_LEFT, / **< Align text to left*/
    LV_TEXT_ALIGN_CENTER, / **< Align text to center*/
    LV_TEXT_ALIGN_RIGHT, / **< Align text to right*/
};
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,

    LV_STATE_USER_1      =  0x1000,
    LV_STATE_USER_2      =  0x2000,
    LV_STATE_USER_3      =  0x4000,
    LV_STATE_USER_4      =  0x8000,

    LV_STATE_ANY = 0xFFFF, 
};

按钮创建

lv_obj_t * lv_btn_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

添加事件回调

struct _lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter,void * user_data)
名称 类型 描述
obj lv_obj_t * 对象
event_cb lv_event_cb_t 回调函数指针
filter lv_event_code_t 何时触发回调
user_data void * 用户数据
返回 struct _lv_event_dsc_t *
常用触发选项
事件类型 说明
LV_EVENT_CLICKED 点击事件(按下并释放)
LV_EVENT_PRESSED 按下事件(无需释放)
LV_EVENT_LONG_PRESSED 长按事件
LV_EVENT_VALUE_CHANGED 值改变事件(如滑块拖动)
LV_EVENT_FOCUSED 对象获得焦点
LV_EVENT_DEFOCUSED 对象失去焦点
LV_EVENT_ALL 监听所有事件

列表创建

lv_obj_t * lv_list_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

创建组

lv_group_t * lv_group_create(void)
名称 类型 描述
返回 lv_group_t * 创建的组的指针

绑定驱动到组

void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group)
名称 类型 描述
indev lv_indev_t * 输入驱动句柄
group lv_group_t * 组指针
返回

设置默认组

void lv_group_set_default(lv_group_t * group)
名称 类型 描述
group lv_group_t * 组指针
返回

控件添加到组

void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
名称 类型 描述
group lv_group_t * 组指针
obj lv_obj_t * 控件指针
返回

控件退出默认组

void lv_group_remove_obj(lv_obj_t * obj)
名称 类型 描述
obj lv_obj_t * 控件指针
返回

设置组编辑模式

void lv_group_set_editing(lv_group_t * group, bool edit)
名称 类型 描述
group lv_group_t * 组指针
edit bool 是否是编辑模式
返回

文本框创建

lv_obj_t * lv_obj_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

文本框设置文本

void lv_textarea_set_text(lv_obj_t * obj, const char * txt)
名称 类型 描述
obj lv_obj_t * 要操作的对象
txt const char * 设置的文本
返回 void

txt不需要全生命周期,内部会拷贝

文本框插入文本

void lv_textarea_add_text(lv_obj_t * obj, const char * txt)
名称 类型 描述
obj lv_obj_t * 要操作的对象
txt const char * 插入的文本
返回 void

txt不需要全生命周期,内部会拷贝

文本框删除光标前侧字符

void lv_textarea_del_char(lv_obj_t * obj)
名称 类型 描述
obj lv_obj_t * 要操作的对象
返回 void

文本框删除光标后侧字符

void lv_textarea_del_char_forward(lv_obj_t * obj)
名称 类型 描述
obj lv_obj_t * 要操作的对象
返回 void

文本框设置光标位置

void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos)
名称 类型 描述
obj lv_obj_t * 要操作的对象
pos int32_t 位置(0表示初始,+从头开始数,-从末尾开始数)
返回 void

pos可以设置为LV_TEXTAREA_CURSOR_LAST将光标移到末尾

pos超过字数则移到末尾

文本框移动光标

void lv_textarea_cursor_up(lv_obj_t * obj)
void lv_textarea_cursor_down(lv_obj_t * obj)
void lv_textarea_cursor_left(lv_obj_t * obj)
void lv_textarea_cursor_right(lv_obj_t * obj)
名称 类型 描述
obj lv_obj_t * 要操作的对象
返回 void

文本框设置占位文字

void lv_textarea_set_placeholder_text(lv_obj_t * obj, const char * txt)
名称 类型 描述
obj lv_obj_t * 要操作的对象
txt const char * 插入的文本
返回 void

txt不需要全生命周期,内部会拷贝

文本框设置单行模式

void lv_textarea_set_one_line(lv_obj_t * obj, bool en)
名称 类型 描述
obj lv_obj_t * 要操作的对象
en bool 是否启用
返回 void

文本框设置文本白名单

void lv_textarea_set_accepted_chars(lv_obj_t * obj, const char * list)
名称 类型 描述
obj lv_obj_t * 要操作的对象
list const char * 白名单列表,如"123"则只允许123写入
返回 void

文本框设置文本最大长度

void lv_textarea_set_max_length(lv_obj_t * obj, uint32_t num)
名称 类型 描述
obj lv_obj_t * 要操作的对象
num uint32_t 最大长度
返回 void

文本框设置密码模式

void lv_textarea_set_password_mode(lv_obj_t * obj, bool en)
名称 类型 描述
obj lv_obj_t * 要操作的对象
en bool 是否启用
返回 void

文本框获取内容

const char * lv_textarea_get_text(const lv_obj_t * obj)
名称 类型 描述
obj lv_obj_t * 要操作的对象
返回 const char * 文本框的文字指针

键盘创建

lv_obj_t * lv_keyboard_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

键盘模式设置

void lv_keyboard_set_mode(lv_obj_t * obj, lv_keyboard_mode_t mode)
名称 类型 描述
obj lv_obj_t * 要操作的对象
mode lv_keyboard_mode_t 键盘模式
返回 void
enum {
    LV_KEYBOARD_MODE_TEXT_LOWER,
    LV_KEYBOARD_MODE_TEXT_UPPER,
    LV_KEYBOARD_MODE_SPECIAL,
    LV_KEYBOARD_MODE_NUMBER,
    LV_KEYBOARD_MODE_USER_1,
    LV_KEYBOARD_MODE_USER_2,
    LV_KEYBOARD_MODE_USER_3,
    LV_KEYBOARD_MODE_USER_4,
};
typedef uint8_t lv_keyboard_mode_t;

控件状态设置

void lv_obj_add_state(lv_obj_t * obj, lv_state_t state)
名称 类型 描述
obj lv_obj_t * 要操作的对象
state lv_state_t 状态
返回 void
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,

    LV_STATE_USER_1      =  0x1000,
    LV_STATE_USER_2      =  0x2000,
    LV_STATE_USER_3      =  0x4000,
    LV_STATE_USER_4      =  0x8000,

    LV_STATE_ANY = 0xFFFF,    / **< Special value can be used in some functions to target all states*/
};

typedef uint16_t lv_state_t;

键盘关联到文本框

void lv_keyboard_set_textarea(lv_obj_t * obj, lv_obj_t * ta)
名称 类型 描述
obj lv_obj_t * 要操作的对象
ta lv_obj_t * 文本框对象
返回 void

样式初始化

void lv_style_init(lv_style_t * style)
名称 类型 描述
style lv_style_t * 样式指针
返回 void

选择子框创建

lv_obj_t * lv_checkbox_create(lv_obj_t * parent)
名称 类型 描述
parent lv_obj_t * 父对象
返回 lv_obj_t * 建立的对象指针

选择子框设置文本

void lv_checkbox_set_text(lv_obj_t * obj, const char * txt)
名称 类型 描述
obj lv_obj_t * 要操作的对象
txt const char * 文本
返回 void

事件获取用户数据

void * lv_event_get_user_data(lv_event_t * e)
名称 类型 描述
e lv_event_t * 事件对象
返回 void * 获取到的数据

事件获取当前激活的对象

lv_obj_t * lv_event_get_current_target(lv_event_t * e)
名称 类型 描述
e lv_event_t * 事件对象
返回 lv_obj_t * 当前激活的对象

触发事件回调后可能会存在传递,即子控件向父控件传递了事件,此时此函数会获取到父控件

事件获取最初激活的对象

lv_obj_t * lv_event_get_target(lv_event_t * e)
名称 类型 描述
e lv_event_t * 事件对象
返回 lv_obj_t * 最初激活的对象

触发事件回调后可能会存在传递,即子控件向父控件传递了事件,此时此函数会获取到子控件

获取子对象

struct _lv_obj_t * lv_obj_get_child(const struct _lv_obj_t * obj, int32_t id);
名称 类型 描述
obj const struct _lv_obj_t * 父对象
id int32_t 子对象ID
返回 struct _lv_obj_t * 获取的子对象

最先创建的为0

最后创建的可以用-1表示

控件清除状态

void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state)
名称 类型 描述
obj lv_obj_t * 要操作的对象
state lv_state_t 要清除的状态
返回 void
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,

    LV_STATE_USER_1      =  0x1000,
    LV_STATE_USER_2      =  0x2000,
    LV_STATE_USER_3      =  0x4000,
    LV_STATE_USER_4      =  0x8000,

    LV_STATE_ANY = 0xFFFF,    / **< Special value can be used in some functions to target all states*/
};

typedef uint16_t lv_state_t;

获取对象在其父对象的编号

uint32_t lv_obj_get_index(const struct _lv_obj_t * obj);
名称 类型 描述
obj const struct _lv_obj_t * obj 父对象
返回 uint32_t 编号

最先创建的是编号0

控件添加标志

void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f)
名称 类型 描述
obj lv_obj_t * 要操作的对象
f lv_obj_flag_t 标志
返回 void
enum {
    LV_OBJ_FLAG_HIDDEN          = (1L << 0),  / **< 隐藏该对象。(就像它根本不存在一样)*/
    LV_OBJ_FLAG_CLICKABLE       = (1L << 1),  / **< 使对象可被输入设备点击*/
    LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2),  / **< 单击时为对象添加焦点状态*/
    LV_OBJ_FLAG_CHECKABLE       = (1L << 3),  / **< 单击对象时切换选中状态*/
    LV_OBJ_FLAG_SCROLLABLE      = (1L << 4),  / **< 使对象可滚动*/
    LV_OBJ_FLAG_SCROLL_ELASTIC  = (1L << 5),  / **< 允许内部滚动,但速度较慢*/
    LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6),  / **< 使对象在“抛出”时进一步滚动*/
    LV_OBJ_FLAG_SCROLL_ONE      = (1L << 7),  / **< 仅允许滚动一个可捕捉的子项*/
    LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), / **< 允许将水平滚动传播到父级*/
    LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), / **< 允许将垂直滚动传播到父级*/
    LV_OBJ_FLAG_SCROLL_CHAIN     = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
    LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10),  / **< 自动滚动对象以使其在聚焦时可见*/
    LV_OBJ_FLAG_SCROLL_WITH_ARROW  = (1L << 11), / **< 允许使用箭头键滚动焦点对象*/
    LV_OBJ_FLAG_SNAPPABLE       = (1L << 12), / **< 如果父对象上启用了滚动捕捉,它可以捕捉到这个对象*/
    LV_OBJ_FLAG_PRESS_LOCK      = (1L << 13), / **< 即使按下的触发从对象上移开,也要保持对象被按下*/
    LV_OBJ_FLAG_EVENT_BUBBLE    = (1L << 14), / **< 将事件传播给父级*/
    LV_OBJ_FLAG_GESTURE_BUBBLE  = (1L << 15), / **< 将手势传播给父级*/
    LV_OBJ_FLAG_ADV_HITTEST     = (1L << 16), / **< 允许执行更精确的点击测试。例如,考虑圆角。*/
    LV_OBJ_FLAG_IGNORE_LAYOUT   = (1L << 17), / **< 通过布局使对象可定位*/
    LV_OBJ_FLAG_FLOATING        = (1L << 18), / **< 当父级滚动时不滚动对象并忽略布局*/
    LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 19), / **< 不要将子级内容剪切到父级边界*/

    LV_OBJ_FLAG_LAYOUT_1        = (1L << 23), / **< 自定义标志,可按布局自由使用*/
    LV_OBJ_FLAG_LAYOUT_2        = (1L << 24), / **< 自定义标志,可按布局自由使用*/

    LV_OBJ_FLAG_WIDGET_1        = (1L << 25), / **< 自定义标志,可通过小部件自由使用*/
    LV_OBJ_FLAG_WIDGET_2        = (1L << 26), / **< 自定义标志,可通过小部件自由使用*/
    LV_OBJ_FLAG_USER_1          = (1L << 27), / **< 自定义标志,可通过用户自由使用*/
    LV_OBJ_FLAG_USER_2          = (1L << 28), / **< 自定义标志,可通过用户自由使用*/
    LV_OBJ_FLAG_USER_3          = (1L << 29), / **< 自定义标志,可通过用户自由使用*/
    LV_OBJ_FLAG_USER_4          = (1L << 30), / **< 自定义标志,可通过用户自由使用*/

};

可以使用|来添加多个标志

控件添加样式

void lv_obj_add_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector);
名称 类型 描述
obj struct _lv_obj_t * 要操作的对象
style lv_style_t * 样式
selector lv_style_selector_t 何时使用样式
返回 void
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,   / **< 标记特定位置,例如文本区域的光标或图表上*/

    LV_PART_CUSTOM_FIRST = 0x080000,    / **< 自定义小部件的扩展点*/

    LV_PART_ANY          = 0x0F0000,    / **< 在某些函数中可以使用特殊值来针对所有部分*/
};

selector可以使用|来添加特定情况的样式

样式设置圆角

void lv_style_set_radius(lv_style_t * style, lv_coord_t value)
名称 类型 描述
style lv_style_t * 样式
value lv_coord_t 圆角大小
返回 void

可以设置大小为LV_RADIUS_CIRCLE以设为圆形

样式设置背景图

void lv_style_set_bg_img_src(lv_style_t * style, const void * value)
名称 类型 描述
style lv_style_t * 样式
value const void * 背景图指针
返回 void

样式设置盒子内边距

void lv_style_set_pad_left(lv_style_t * style, lv_coord_t value)
void lv_style_set_pad_right(lv_style_t * style, lv_coord_t value)
void lv_style_set_pad_top(lv_style_t * style, lv_coord_t value)
void lv_style_set_pad_bottom(lv_style_t * style, lv_coord_t value)

static inline void lv_style_set_pad_all(lv_style_t * style, lv_coord_t value)
名称 类型 描述
style lv_style_t * 样式
value lv_coord_t 边距
返回 void

样式设置网格布局行/列间间距

void lv_style_set_pad_column(lv_style_t * style, lv_coord_t value)
void lv_style_set_pad_row(lv_style_t * style, lv_coord_t value)
名称 类型 描述
style lv_style_t * 样式
value lv_coord_t 间距
返回 void
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐