LVGL入门

目前配置好的初始化代码放在gitee仓库,适合我目前GEC6818开发板的运行,详细的学习请上LVGL百问网


LVGL

一、源码结构

要使用 LVGL,首先得对其源码结构有较清晰的认识,下面是 LVGL 9.2 源码的结构:

路径 文件/目录 说明
/ CMakeLists.txt 顶层 CMake 配置文件,控制整个工程的编译
/ lv_conf.h LVGL 配置文件
/lvgldemos/ 官方提供的综合案例代码
/lvglenv_support/ LVGL 对各种平台的支持配置文件(ESP、RTT、Zephyr 等)
/lvgl/env_support/cmake/ custom.cmake 默认的真正的 CMake 配置信息,可控制 LVGL 库编译形态(动态/静态)
/lvgl/examples/anim/ 动画相关官方示例代码
/lvgl/examples/event/ 事件相关官方示例代码
/lvgl/examples/layouts/ 布局相关官方示例代码
/lvgl/examples/libs/ffmpeg/ 第三方音视频库 FFmpeg 相关官方示例代码
/lvgl/examples/libs/freetype/ 第三方字库 FreeType 相关官方示例代码
/lvgl/examples/libs/widgets/ 基础控件相关官方示例代码
/lvgl/src/core/ LVGL 核心代码,提供基本对象 lv_obj_t 的实现
/lvgl/src/display/ 显示控制核心代码
/lvgl/src/osal/ 操作系统硬件抽象层
/lvgl/src/widgets/ LVGL 控件实现代码

二、基础控件

按钮

/lvgl/examples/widgets/btn    //路径

示例代码:

void lv_example_btn_1(void)
{
    lv_obj_t * label;

    // 创建一个btn控件
    // lv_scr_act() 获取并返回当前活跃的屏幕
    // 因此bnt按钮实际上是在当前屏幕上创建的
    lv_obj_t * btn1 = lv_btn_create(lv_scr_act());

    // 设置对齐方式,以及偏移量
    lv_obj_align(btn1, LV_ALIGN_TOP_MID, 0, 5);
    // 设置宽高大小
    lv_obj_set_size( btn1 , 200 , 80 );

    // 给对象btn添加一个事件回调函数
    // LV_EVENT_CLICKED 触发回调的事件设置为点击事件
    static int Num = 123 ; // 普通遍历会随着函数结束而释放
    // 因此需要作为参数传递给回调函数就必须保证他的声明周期能覆盖回调函数
    // 静态 、 堆
    lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_CLICKED, &Num );
}

接口分析:

/**
 * Add an event handler function for an object.
 * Used by the user to react on event which happens with the object.
 * An object can have multiple event handler. They will be called in the same order as they were added.
 * @param obj       pointer to an object
 * @param filter    and event code (e.g. `LV_EVENT_CLICKED`) on which the event should be called. `LV_EVENT_ALL` can be sued the receive all the events.
 * @param event_cb  the new event function
 * @param           user_data custom data data will be available in `event_cb`
 * @return          a pointer the event descriptor. Can be used in ::lv_obj_remove_event_dsc
 */
struct _lv_event_dsc_t * lv_obj_add_event_cb(
    struct _lv_obj_t * obj,      // 要添加事件的对象
    lv_event_cb_t event_cb,      // 事件回调函数
    lv_event_code_t filter,      // 事件类型过滤器,用于指定哪个事件触发回调
    void * user_data             // 用户自定义数据,给回调函数传递的参数
);

回调函数的类型:
typedef void (*lv_event_cb_t)(lv_event_t *e)

void  myFunc(lv_event_t *e)
{
    // 响应程序    
}

常见事件:

输入设备事件

LV_EVENT_PRESSED              // 对象被按下
LV_EVENT_PRESSING             // 对象持续按下时连续触发
LV_EVENT_PRESS_LOST           // 按下后滑出对象范围
LV_EVENT_SHORT_CLICKED        // 短点击(未滚动)
LV_EVENT_LONG_PRESSED         // 长按(超过 long_press_time)
LV_EVENT_LONG_PRESSED_REPEAT  // 长按后定期重复触发
LV_EVENT_CLICKED              // 点击释放(未滚动)
LV_EVENT_RELEASED             // 释放(所有情况)
LV_EVENT_SCROLL_BEGIN         // 开始滚动
LV_EVENT_SCROLL_END           // 结束滚动
LV_EVENT_SCROLL               // 滚动中
LV_EVENT_GESTURE              // 手势检测
LV_EVENT_KEY                  // 按键事件

焦点事件

LV_EVENT_FOCUSED              // 获得焦点
LV_EVENT_DEFOCUSED            // 失去焦点
LV_EVENT_LEAVE                // 失去焦点但仍选中
LV_EVENT_HIT_TEST             // 高级点击测试

绘图事件

LV_EVENT_COVER_CHECK          // 覆盖检查
LV_EVENT_REFR_EXT_DRAW_SIZE   // 获取额外绘制区域
LV_EVENT_DRAW_MAIN_BEGIN      // 开始主绘制阶段
LV_EVENT_DRAW_MAIN            // 主绘制
LV_EVENT_DRAW_MAIN_END        // 结束主绘制阶段
LV_EVENT_DRAW_POST_BEGIN      // 开始后绘制阶段(子对象绘制后)
LV_EVENT_DRAW_POST            // 后绘制
LV_EVENT_DRAW_POST_END        // 结束后绘制阶段
LV_EVENT_DRAW_PART_BEGIN      // 开始绘制部件
LV_EVENT_DRAW_PART_END        // 结束绘制部件

特殊事件

LV_EVENT_VALUE_CHANGED        // 对象值改变
LV_EVENT_INSERT               // 文本插入
LV_EVENT_REFRESH              // 刷新通知
LV_EVENT_READY                // 进程完成
LV_EVENT_CANCEL               // 进程取消

对象生命周期事件

LV_EVENT_DELETE               // 对象被删除
LV_EVENT_CHILD_CHANGED        // 子对象变化
LV_EVENT_CHILD_CREATED        // 子对象创建
LV_EVENT_CHILD_DELETED        // 子对象删除
LV_EVENT_SIZE_CHANGED         // 对象尺寸变化
LV_EVENT_STYLE_CHANGED        // 样式变化
LV_EVENT_LAYOUT_CHANGED       // 布局变化

屏幕事件

LV_EVENT_SCREEN_UNLOAD_START  // 屏幕开始卸载
LV_EVENT_SCREEN_LOAD_START    // 屏幕开始加载
LV_EVENT_SCREEN_LOADED        // 屏幕加载完成
LV_EVENT_SCREEN_UNLOADED      // 屏幕卸载完成

三、样式

1. 样式的特点

1.一个样式可以给多个对象使用(正常样式)样式可以级联,也就是可以将多个样式分配给一个对象。所以,我们不用将所有属性都在一个样式中指定,可以通过多个样式组合的形式指定。 LVGL 会优先使用我们定义的样式,如果没有就会使用默认值。

2.后来添加的样式具有更高的优先级。也就是说如果在两种样式中指定了同一个属性,则将使用最后添加的样式。

3.如果对象中未指定某些属性(例如文本颜色),就会从父级继承。

4.对象可以有“本地样式”,它比普通样式具有更高的优先级。

5.可以定义有过渡效果的样式。

6.默认有一个样式主题,我们也可以自己定义样式主题,作为默认的样式主题使用。

2. 使用样式三板斧(操作流程)

① 初始化样式

样式存储在lv_style_t变量中。样式变量应该是 静态 、全局或动态分配 的。 也就是它们不能是函数中的局部变量,因为当函数结束时它们会被销毁。

static lv_style_t style;
lv_style_init(&style);

② 设置样式属性

样式就是控件外观的表达,其属性多种多样,他们的API接口函数通常如下所示:

lv_style_set_xxxxxx();

常见样式:

// 背景颜色
lv_style_set_bg_color(&style, lv_color_hex(0x3F8DF7));
lv_style_set_bg_opa(&style, LV_OPA_100);          // 不透明度 0-255

// 背景渐变
lv_style_set_bg_grad_color(&style, lv_color_hex(0x2C6BC5));
lv_style_set_bg_grad_dir(&style, LV_GRAD_DIR_VER); // 渐变方向
lv_style_set_bg_main_stop(&style, 0);             // 主色停止点
lv_style_set_bg_grad_stop(&style, 255);           // 渐变色停止点

// 背景图片
lv_style_set_bg_img_src(&style, &img_cogwheel);   // 图片源
lv_style_set_bg_img_opa(&style, LV_OPA_50);       // 图片不透明度

// 边框基本属性
lv_style_set_border_color(&style, lv_color_black());
lv_style_set_border_opa(&style, LV_OPA_100);
lv_style_set_border_width(&style, 2);             // 边框宽度

// 边框高级属性
lv_style_set_border_side(&style, LV_BORDER_SIDE_FULL); // 边框边
lv_style_set_border_post(&style, true);           // 后绘制边框

// 轮廓样式设置
lv_style_set_outline_width(&style, 4);
lv_style_set_outline_color(&style, lv_color_hex(0x8BC34A));
lv_style_set_outline_opa(&style, LV_OPA_50);
lv_style_set_outline_pad(&style, 8);              // 轮廓与边框间距

// 阴影样式设置
lv_style_set_shadow_width(&style, 10);            // 阴影宽度
lv_style_set_shadow_color(&style, lv_color_hex(0x333333));
lv_style_set_shadow_opa(&style, LV_OPA_30);
lv_style_set_shadow_ofs_x(&style, 5);             // X偏移
lv_style_set_shadow_ofs_y(&style, 5);             // Y偏移
lv_style_set_shadow_spread(&style, 3);            // 阴影扩散

// 内边距设置
lv_style_set_pad_all(&style, 10);                 // 所有方向内边距
lv_style_set_pad_top(&style, 5);
lv_style_set_pad_bottom(&style, 5);
lv_style_set_pad_left(&style, 8);
lv_style_set_pad_right(&style, 8);
lv_style_set_pad_row(&style, 6);                  // 行间距
lv_style_set_pad_column(&style, 8);               // 列间距

// 尺寸和位置设置
lv_style_set_width(&style, 100);
lv_style_set_min_width(&style, 80);
lv_style_set_max_width(&style, 200);
lv_style_set_height(&style, 60);
lv_style_set_min_height(&style, 40);
lv_style_set_max_height(&style, 120);
lv_style_set_x(&style, 10);
lv_style_set_y(&style, 20);
lv_style_set_align(&style, LV_ALIGN_CENTER);

// 变换设置
lv_style_set_transform_width(&style, 20);
lv_style_set_transform_height(&style, -10);
lv_style_set_transform_zoom(&style, 256);         // 256 = 1.0倍
lv_style_set_transform_angle(&style, 300);        // 0.3度 * 10
lv_style_set_transform_pivot_x(&style, 50);
lv_style_set_transform_pivot_y(&style, 50);


// 字体设置
lv_style_set_text_color(&style, lv_color_white());
lv_style_set_text_opa(&style, LV_OPA_100);
lv_style_set_text_font(&style, &lv_font_montserrat_16);
lv_style_set_text_letter_space(&style, 2);        // 字间距
lv_style_set_text_line_space(&style, 8);          // 行间距
lv_style_set_text_decor(&style, LV_TEXT_DECOR_UNDERLINE); // 文本装饰
lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER);    // 文本对齐


// 图像样式设置
lv_style_set_img_opa(&style, LV_OPA_80);
lv_style_set_img_recolor(&style, lv_color_hex(0xFF0000));
lv_style_set_img_recolor_opa(&style, LV_OPA_50);

// 线条样式设置
lv_style_set_line_width(&style, 3);
lv_style_set_line_dash_width(&style, 10);         // 虚线宽度
lv_style_set_line_dash_gap(&style, 5);            // 虚线间隙
lv_style_set_line_rounded(&style, true);          // 圆角端点
lv_style_set_line_color(&style, lv_color_hex(0x2196F3));
lv_style_set_line_opa(&style, LV_OPA_100);

// 弧线样式设置
lv_style_set_arc_width(&style, 8);
lv_style_set_arc_rounded(&style, true);           // 圆角端点
lv_style_set_arc_color(&style, lv_color_hex(0x4CAF50));
lv_style_set_arc_opa(&style, LV_OPA_100);
lv_style_set_arc_img_src(&style, &img_arc);       // 弧线图片


// 动画和过渡设置
static lv_style_transition_dsc_t trans;
static lv_style_prop_t props[] = {LV_STYLE_BG_COLOR, LV_STYLE_BORDER_COLOR, 0};
lv_style_transition_dsc_init(&trans, props, lv_anim_path_ease_out, 300, 0, NULL);
lv_style_set_transition(&style, &trans);

③ 将样式添加到指定对象

当我们初始化并且设置好一个样式之后就可以将它添加到对象上面了,接口函数是:

lv_obj_add_style(btn1 , &style , 0 );


void lv_obj_add_style(
    lv_obj_t *obj,               // 指向要添加样式的对象
    const lv_style_t *style,     // 指向已初始化好的样式
    lv_style_selector_t selector // 指定样式应作用的部分(part)和状态(state)
);


参数说明
obj:目标对象指针(如按钮、标签等控件实例)。
style:已初始化(lv_style_init)的样式结构体地址。
selector:
用按位或组合 LV_PART_* 与 LV_STATE_*,告诉 LVGL 该样式应应用到对象的哪一部分、在何种状态下生效。
常用示例:
0 或 LV_PART_MAIN | LV_STATE_DEFAULT → 默认外观
LV_STATE_PRESSED → 按下时的主部件
LV_PART_SCROLLBAR | LV_STATE_SCROLLED → 滚动时的滚动条
posted @ 2025-11-17 18:39  Jaklin  阅读(188)  评论(0)    收藏  举报