解码LVGL基础

news/2025/11/1 18:45:20/文章来源:https://www.cnblogs.com/YouEmbedded/p/19181246

LVGL9.2 源码结构

LVGL9.2 源码按功能模块化划分,核心目录及文件的详细作用如下:

路径 核心文件 / 子目录 功能说明
/ CMakeLists.txt 顶层编译配置文件,控制整个工程的编译规则:
- 可指定编译类型(静态库STATIC/ 动态库SHARED);
- 配置编译器选项(如 -O3 优化、-Wall 警告检查);
- 关联子目录(如lvgl/lv_drivers/)的编译。
/ lv_conf.h LVGL 全局配置文件,决定控件启用、内存大小、显示特性:
- 启用核心控件(如LV_USE_BTN按钮、LV_USE_LABEL标签);
- 设置显示参数(如LV_HOR_RES_MAX屏幕宽度、LV_VER_RES_MAX屏幕高度);
- 配置内存池大小(如LV_MEM_SIZE,默认 32KB)。
/lvgl demos/ 官方综合案例,覆盖复杂 UI 场景:
- 如lv_demo_widgets():展示所有基础控件的组合使用;
- 如lv_demo_benchmark():测试 LVGL 渲染性能(帧率、内存占用);
- 案例可直接调用,快速验证硬件兼容性。
/lvgl examples/ 基础功能示例,按模块分类:
- anim/:动画示例(如lv_example_anim_1()实现控件平移);
- event/:事件示例(如按钮单击、滑动条数值变化);
- layouts/:布局示例(如弹性布局、网格布局);
- libs/:第三方库示例(FFmpeg 音视频、FreeType 字体)。
/lvgl/env_support/ 平台支持配置文件 适配不同硬件 / 系统的 “桥梁”:
- esp/:ESP32/ESP8266 平台配置(如 GPIO 映射、SPI 屏幕驱动);
- rtthread/:RT-Thread 实时系统适配(线程创建、定时器绑定);
- zephyr/:Zephyr 操作系统适配(设备树集成、驱动注册);
- cmake/custom.cmake:控制 LVGL 库编译形态(动态库 / 静态库),可自定义编译选项。
/lvgl/src core/ LVGL 核心模块,决定对象、事件、样式的底层实现:
- lv_obj.c:基础对象lv_obj_t的创建、删除、属性设置(如位置、大小);
- lv_event.c:事件系统(绑定、触发、冒泡);
- lv_style.c:样式系统(属性设置、状态管理);
- lv_obj_tree.c:对象树管理(父子关系维护、内存递归释放)。
/lvgl/src display/ 显示控制核心,负责屏幕数据输出:
- lv_display.c:屏幕初始化(分辨率设置、刷新回调注册);
- lv_draw.c:绘图 API(点、线、矩形、文本绘制);
- lv_buf.c:显示缓冲区管理(双缓冲 / 单缓冲配置,避免屏幕闪烁)。
/lvgl/src osal/ 操作系统抽象层,解耦 LVGL 与具体 OS:
- 提供通用接口:lv_thread_create()(创建线程)、lv_mutex_lock()(互斥锁)、lv_timer_create()(定时器);
- 无 OS 场景(如裸机):提供lv_os_alrtos.c适配,模拟线程与定时器。
/lvgl/src widgets/ 所有控件的实现目录,每个控件对应独立.c文件:
- lv_btn.c:按钮控件(单击、长按、禁用状态);
- lv_label.c:标签控件(文本设置、对齐、换行);
- lv_img.c:图像控件(RGB 数据显示、文件加载);
- lv_textarea.c:输入框控件(文本输入、密码模式、光标管理)。

运行官方案例

调用lv_example_anim_1()实现动画案例,完整代码(含 LVGL 初始化、显示 / 输入设备适配):

函数分析:

/*** 获取当前活跃的顶层屏幕对象* @return  当前活跃的顶层屏幕对象指针(lv_obj_t*),作为控件的父对象* @note    LVGL中所有控件需依赖父对象显示,顶层屏幕是最顶层的容器对象;*          若没有活跃屏幕,可能返回NULL,需确保调用前已初始化屏幕系统*/
lv_obj_t * lv_screen_active(void);/*** 创建标签控件* @param parent  父对象指针(lv_obj_t*),标签将依附于该父对象显示* @return        新创建的标签控件对象指针(lv_obj_t*),用于后续操作标签* @note          标签是LVGL中用于显示文本的基础控件;*                需通过其他接口(如lv_label_set_text)设置显示内容后才会呈现文本*/
lv_obj_t * lv_label_create(lv_obj_t * parent);/*** 设置标签控件的显示文本* @param label  标签对象指针(lv_obj_t*),需为已创建的标签控件* @param text   待显示的文本字符串(const char*),支持ASCII字符* @return       无返回值(void)* @note         若需显示中文/特殊字符,需提前配置对应字库,否则可能显示乱码;*               文本内容会覆盖标签原有的显示内容*/
void lv_label_set_text(lv_obj_t * label, const char * text);/*** 设置对象在父对象中的位置* @param obj  目标对象指针(lv_obj_t*),可为任意LVGL控件* @param x    X轴坐标(int32_t),相对于父对象左上角的水平偏移量(向右为正)* @param y    Y轴坐标(int32_t),相对于父对象左上角的垂直偏移量(向下为正)* @return     无返回值(void)* @note       坐标原点为父对象左上角;*             该函数会覆盖对象之前的布局设置(如居中、对齐等)*/
void lv_obj_set_pos(lv_obj_t * obj, int32_t x, int32_t y);/*** 创建开关控件* @param parent  父对象指针(lv_obj_t*),开关将依附于该父对象显示* @return        新创建的开关控件对象指针(lv_obj_t*),用于后续操作开关* @note          开关是二态交互控件,支持选中(LV_STATE_CHECKED)和未选中状态;*                态变化可通过LV_EVENT_VALUE_CHANGED事件捕获*/
lv_obj_t * lv_switch_create(lv_obj_t * parent);/*** 使对象在父对象中居中显示* @param obj  目标对象指针(lv_obj_t*),可为任意LVGL控件* @return     无返回值(void)* @note       同时实现水平和垂直方向居中,无需手动计算坐标;*             父对象大小变化时,对象会自动保持居中(需开启布局更新机制)*/
void lv_obj_center(lv_obj_t * obj);/*** 为对象添加状态标记* @param obj    目标对象指针(lv_obj_t*),可为任意LVGL控件* @param state  状态标记(lv_state_t),如LV_STATE_CHECKED(选中)、LV_STATE_DISABLED(禁用)等* @return       无返回值(void)* @note         状态会影响控件的外观(如开关选中时的滑块位置、颜色);*               可通过lv_obj_clear_state移除状态*/
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);/*** 为对象绑定事件回调函数* @param obj      目标对象指针(lv_obj_t*),事件源对象* @param cb(callback)       回调函数指针(lv_event_cb_t),事件触发时执行的函数* @param event    事件类型(lv_event_t),如LV_EVENT_VALUE_CHANGED(值变化)、LV_EVENT_CLICKED(点击)等* @param user_data  用户数据(void*),传递给回调函数的自定义数据(如关联的其他控件)* @return         无返回值(void)* @note           同一对象可绑定多个不同类型的事件,或同一事件绑定多个回调;*                 回调函数中可通过lv_event_get_target()获取事件源,lv_event_get_user_data()获取用户数据*/
void lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t cb, lv_event_t event, void * user_data);

image

/*** LVGL动画示例函数:创建标签与开关控件,通过开关状态变化触发标签动画(需配合回调函数实现完整动画逻辑)*/
void lv_example_anim_1(void)
{/* 创建标签控件:创建对象时需指定父对象,此处父对象为当前活跃的顶层屏幕,所有控件需依赖父对象完成显示* 标签是常用基础控件,主要用于显示文本类信息,需绑定到父对象后才能在界面上呈现*/lv_obj_t * label = lv_label_create(lv_screen_active());/* 设置标签文本内容:标签控件通过该接口定义显示的具体文本,支持英文、数字等基础字符* 若需显示中文,需额外配置对应的中文字库,确保文本能正常渲染不出现乱码*/lv_label_set_text(label, "Hello animations!");/* 设置标签位置:通过指定X、Y坐标控制对象在父对象中的显示位置,坐标原点为父对象左上角* 此处X=100像素、Y=10像素,意味着标签从屏幕左上角向右偏移100像素、向下偏移10像素显示*/lv_obj_set_pos(label, 100, 10);/* 创建开关控件:开关是具有二态(选中/未选中)的交互控件,可用于触发状态相关的逻辑* 同样需指定父对象为当前活跃屏幕,确保与标签在同一界面层级显示*/lv_obj_t * sw = lv_switch_create(lv_screen_active());/* 开关居中显示:通过简化的居中接口,让开关在父对象(屏幕)中水平和垂直方向均居中* 无需手动计算坐标,直接通过对齐逻辑实现控件在父对象内的居中布局*/lv_obj_center(sw);/* 设置开关为选中状态:控件存在多种状态(如默认、选中、禁用等),此接口为开关添加选中状态* 选中状态下,开关会呈现预设的开启样式(如滑块滑动到一侧、背景色变化等),与未选中状态形成视觉区分*/lv_obj_add_state(sw, LV_STATE_CHECKED);/* 为开关绑定数值变化事件:当开关状态(选中/未选中)发生改变时,触发指定的回调函数* 同时将标签控件作为用户数据传递给回调,便于在回调中操作标签(如控制标签动画)* 事件触发的核心逻辑需在回调函数(sw_event_cb)中实现,此处仅完成事件与对象的绑定*/lv_obj_add_event_cb(sw, sw_event_cb, LV_EVENT_VALUE_CHANGED, label);
}

效果

image

LVGL对象模型

LVGL 用 C 语言模拟面向对象思想,核心是lv_obj_t基础对象。

image

核心概念:基类与子类

  • 基类(lv_obj_t):所有控件的 “父类”,定义通用属性(位置、大小、样式、父子关系)和行为(创建、删除)。
  • 子类(控件):如按钮(lv_btn_t)、标签(lv_label_t),继承lv_obj_t的所有属性,同时扩展自身特性(自身属性依赖宏的条件编译实现)
    • 按钮:新增 “按下状态”“点击事件”;
    • 标签:新增 “文本内容”“字体样式”;
    • 所有子类创建时需指定父对象(如lv_btn_create(parent)),父对象可为lv_scr_act()(当前活跃屏幕)或其他控件。

父子对象关系

lv_obj_t (类)定义了控件的抽象特点,其定义包含了数据的形式以及对数据的操作。控件(子类)比原本的类(称为父类或基类)要更加具体化,子类会继承父类的属性和行为。定义一个对象时,可以给这个对象指定它的父对象。

视觉关系:子对象受父对象约束

标签左半部分移出屏幕,超出部分不可见(默认裁剪)

图示:

image

视觉关系:子对象跟随父对象移动

父对象可拖拽,子对象同步移动

图示:

image

内存关系:删除父对象,子对象自动释放

“父对象管理子对象内存”

图示:

image

基础对象常用接口

大小与位置设置

/*** 单独设置对象的宽度* @param obj  目标对象指针(lv_obj_t*,不可为NULL)* @param w    宽度值(int32_t)coord:坐标,支持两种类型:像素值(如300);*						 父对象宽度百分比(如LV_PCT(50)表示父对象宽度的50%)* @return     无返回值(void)* @note       仅修改宽度,高度保持不变;*             会覆盖通过lv_obj_set_size()设置的宽度值;*             若使用百分比,实际宽度会随父对象宽度变化自动更新*/
void lv_obj_set_width(lv_obj_t * obj, int32_t w);/*** 单独设置对象的高度* @param obj  目标对象指针(lv_obj_t*,不可为NULL)* @param h    高度值(int32_t),支持三种类型:像素值;*             父对象高度百分比(LV_PCT(n));*             自适应内容高度(LV_SIZE_CONTENT)* @return     无返回值(void)* @note       仅修改高度,宽度保持不变;*             会覆盖通过lv_obj_set_size()设置的高度值;*             设为LV_SIZE_CONTENT时,高度会自动适配对象内部内容(如子对象、文本)的实际高度*/
void lv_obj_set_height(lv_obj_t * obj, int32_t h);/*** 同时设置对象的宽度和高度* @param obj   目标对象指针(lv_obj_t*,不可为NULL)* @param w     宽度值(int32_t),支持像素值或父对象宽度百分比(LV_PCT(n))* @param h     高度值(int32_t),支持像素值、父对象高度百分比(LV_PCT(n))或自适应内容(LV_SIZE_CONTENT)* @return      无返回值(void)* @note        会同时覆盖对象之前的宽度和高度设置;*              宽高单位可混合使用(如宽度用百分比,高度用像素)*/
void lv_obj_set_size(lv_obj_t * obj, int32_t w, int32_t h);/*** 获取对象的实际宽度(像素值)* @param obj  目标对象指针(lv_obj_t*,不可为NULL)* @return     实际宽度(int32_t),单位为像素* @note       无论设置时使用像素、百分比还是其他单位,均返回最终渲染的实际像素宽度;*             若对象未完成渲染,可能返回初始默认值(如0)*/
int32_t lv_obj_get_width(lv_obj_t * obj);/*** 获取对象的实际高度(像素值)* @param obj  目标对象指针(lv_obj_t*,不可为NULL)* @return     实际高度(int32_t),单位为像素* @note       无论设置时使用何种单位,均返回最终渲染的实际像素高度;*             若设置为LV_SIZE_CONTENT,返回值会随内部内容变化而更新*/
int32_t lv_obj_get_height(lv_obj_t * obj);/*** 单独设置对象的X轴坐标(相对于父对象)* @param obj  目标对象指针(lv_obj_t*)* @param x    X轴坐标(int32_t),以父对象左上角为原点,正数向右、负数向左* @return     无返回值(void)* @note       仅修改X坐标,Y坐标保持不变;*             会覆盖通过lv_obj_set_pos()设置的X坐标值*/
void lv_obj_set_x(lv_obj_t * obj, int32_t x);/*** 单独设置对象的Y轴坐标(相对于父对象)* @param obj  目标对象指针(lv_obj_t*)* @param y    Y轴坐标(int32_t),以父对象左上角为原点,正数向下、负数向上* @return     无返回值(void)* @note       仅修改Y坐标,X坐标保持不变;*             会覆盖通过lv_obj_set_pos()设置的Y坐标值*/
void lv_obj_set_y(lv_obj_t * obj, int32_t y);/*** 同时设置对象的X、Y轴坐标(相对于父对象)* @param obj  目标对象指针(lv_obj_t*)* @param x    X轴坐标(int32_t),正数向右、负数向左* @param y    Y轴坐标(int32_t),正数向下、负数向上* @return     无返回值(void)* @note       会同时覆盖对象之前的X、Y坐标设置;*             坐标原点为父对象左上角,单位为像素*/
void lv_obj_set_pos(lv_obj_t * obj, int32_t x, int32_t y);/*** 获取对象的实际X轴坐标(相对于父对象)* @param obj  目标对象指针(lv_obj_t*,不可为NULL)* @return     实际X坐标(int32_t),单位为像素* @note       返回值为相对于父对象左上角的最终坐标,受布局调整(如对齐、居中)影响;*             与lv_obj_set_x()设置值一致(无自动布局时)*/
int32_t lv_obj_get_x(lv_obj_t * obj);/*** 获取对象的实际Y轴坐标(相对于父对象)* @param obj  目标对象指针(lv_obj_t*,不可为NULL)* @return     实际Y坐标(int32_t),单位为像素* @note       返回值为相对于父对象左上角的最终坐标,受布局调整影响;*             与lv_obj_set_y()设置值一致(无自动布局时)*/
int32_t lv_obj_get_y(lv_obj_t * obj);

对齐方式设置

/*** 相对于父对象进行对齐(快速定位对象在父容器中的位置)* @param obj        目标对象指针(lv_obj_t*,不可为NULL),需对齐的对象* @param align      对齐方式(lv_align_t),指定对象相对于父对象的对齐基准点*                   常见取值:LV_ALIGN_CENTER(父对象中心)、LV_ALIGN_TOP_LEFT(父对象左上角)、*                   LV_ALIGN_BOTTOM_RIGHT(父对象右下角)、LV_ALIGN_LEFT_MID(父对象左侧中间)等* @param x_offset   X轴偏移量(int32_t),基于对齐基准点的水平偏移(正数向右,负数向左)* @param y_offset   Y轴偏移量(int32_t),基于对齐基准点的垂直偏移(正数向下,负数向上)* @return           无返回值(void)* @note             对齐基准为目标对象的父对象,若对象无父对象(顶层对象),则相对于屏幕对齐;*                   会覆盖对象之前通过 lv_obj_set_pos()/lv_obj_set_x()/lv_obj_set_y() 设置的位置;*                   父对象大小变化时,若开启布局自动更新,对象会重新保持对齐状态*/
void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_offset, int32_t y_offset);/*** 将目标对象相对于基准对象进行对齐* @param obj       要对齐的目标对象指针(lv_obj_t*,必须指向有效对象,不可为NULL)* @param base      基准对象指针(const lv_obj_t*,可为NULL;若为NULL,默认以目标对象的父对象为基准)* @param align     对齐方式(lv_align_t),指定目标对象与基准对象的对齐点(如LV_ALIGN_TOP_LEFT表示目标对象左上角与基准对象左上角对齐,LV_ALIGN_CENTER表示中心点对齐等)* @param x_ofs     X轴偏移量(int32_t),单位为像素;在对齐基础上,目标对象沿X轴偏移的距离(正值向右,负值向左)* @param y_ofs     Y轴偏移量(int32_t),单位为像素;在对齐基础上,目标对象沿Y轴偏移的距离(正值向下,负值向上)* @note           对齐逻辑:根据`align`参数定义的对齐点,先将目标对象的指定点与基准对象的对应点重合,再应用`x_ofs`和`y_ofs`偏移;*                 `lv_align_t`枚举包含多种预定义对齐方式(如边缘对齐、角对齐、中心对齐等),可覆盖大部分常见布局场景;*                 若基准对象`base`被移动或尺寸改变,目标对象不会自动重新对齐,需手动再次调用该函数更新位置*/
void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, int32_t x_ofs, int32_t y_ofs);

圆角设置

/*** 设置对象指定部分的圆角样式(控制对象边角的圆润程度)* @param obj       目标对象指针(lv_obj_t*,不可为NULL),需设置圆角的对象(如按钮、容器等)* @param value     圆角半径(int32_t),单位为像素;特殊值LV_RADIUS_CIRCLE表示完全圆形(需对象宽高相等时生效)* @param selector  样式选择器(lv_style_selector_t),用于指定应用该样式的对象部分(part)和状态(state)*                  通常通过LV_PART_XXX(如LV_PART_MAIN,主体部分)和LV_STATE_XXX(如默认状态0)组合而成* @return          无返回值(void)* @note            圆角半径越大,对象边角越圆润;半径为0时边角为直角;*                  若对象宽高不相等,使用LV_RADIUS_CIRCLE会生成椭圆形边角,而非正圆形;*                  同一对象的不同部分(如主体、边框)和不同状态(如默认、选中)可设置不同圆角样式;*                  会覆盖之前对同一选择器(相同part和state)设置的圆角样式*/
void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);

LVGL盒子模型

LVGL 遵循 CSS 的 border-box 模型。

盒子模型组成

LVGL 盒子模型的 5 个组成部分:

image

组成部分 定义 核心调整接口
Bounding(边界) 对象的 “外框”,即lv_obj_set_size设置的宽高范围,包含 Border、Padding、Content,是对象的整体尺寸。 lv_obj_set_size():设置边界宽高;
lv_obj_get_width():获取边界宽度。
Border(边框) 边界内侧的线条,占 Bounding 空间,可设置宽度、颜色、样式(实线 / 虚线),用于美化对象边框。 lv_obj_set_style_border_width():边框宽度;
lv_obj_set_style_border_color():边框颜色。
Padding(内边距) 边框内侧与 Content 的间距,控制子对象与父对象边框的距离(子对象不会超出 Padding 范围)。 lv_obj_set_style_pad_top():上内边距;
lv_obj_set_style_pad_left():左内边距;
lv_obj_set_style_pad_all():所有内边距统一设置。
Content(内容区) 实际显示内容的区域(如标签的文本、图像的像素),尺寸 = Bounding 宽高 - 2×Border 宽度 - 2×Padding。 由内容自动决定(如标签文本长度、图像尺寸),无需手动设置。
Outline(轮廓) 边框外侧的线条,不占空间,仅用于视觉突出(如输入框聚焦时的高亮框),不会影响对象布局。 lv_obj_set_style_outline_width():轮廓宽度;
lv_obj_set_style_outline_color():轮廓颜色。

自定义测试代码

创建mycode/目录、配置CMakeLists.txt、测试运行,补充完整的自定义代码结构及编译配置:

目录结构

项目根目录/
├── bin/                # 编译输出目录(可执行文件)
├── build/              # 编译中间文件目录
├── cmake/              # CMake辅助配置
├── lvgl/               # LVGL源码目录
├── mycode/             # 自定义代码目录(《基础.docx》新增)
│   ├── obj.c        # 基础对象测试代码
│   └── head.h          # 自定义头文件(声明函数)
├── CMakeLists.txt      # 顶层CMake配置文件
├── main.c              # 主函数(调用自定义测试代码)
└── lv_conf.h           # LVGL配置文件

自定义头文件mycode/head.h

#ifndef MYCODE_HEAD_H
#define MYCODE_HEAD_H
#include "lvgl/lvgl.h"
// 声明自定义测试函数
void obj_test(void);          // 基础对象测试#endif // MYCODE_HEAD_H

自定义代码mycode/test.c

#include "head.h"
/*** 基础对象测试函数*/
void obj_test(void) {// 获取当前活跃屏幕(父对象)lv_obj_t *scr = lv_scr_act();// 在屏幕中创建基础对象(子对象)lv_obj_t *obj = lv_obj_create(scr);// 设置基础对象属性(大小、位置、对齐、样式)lv_obj_set_size(obj, 180, 120);                // 大小:180×120像素lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0);      // 居中显示lv_obj_set_style_bg_color(obj, lv_color_hex(0xF0F8FF), LV_PART_MAIN);  // 背景色:爱丽丝蓝lv_obj_set_style_radius(obj, 8, LV_PART_MAIN, 0);  // 圆角:8像素lv_obj_set_style_border_width(obj, 2, LV_PART_MAIN);  // 边框:2像素lv_obj_set_style_border_color(obj, lv_color_hex(0x87CEEB), LV_PART_MAIN);  // 边框色:天蓝色// 在基础对象上创建子标签(显示文本)lv_obj_t *label = lv_label_create(obj);lv_label_set_text(label, "hello");lv_obj_set_style_text_font(label, &lv_font_montserrat_18, LV_PART_MAIN);  // 字体:18号lv_obj_center(label);  // 标签在基础对象内居中
}

配置CMakeLists.txt

补充完整的顶层CMakeLists.txt,确保mycode/目录下的代码被编译:

# 顶层 CMakeLists.txt
...
...# 新增如下两行
include_directories(${PROJECT_SOURCE_DIR}/mycode)
file(GLOB_RECURSE MY_SOURCES ${PROJECT_SOURCE_DIR}/mycode/*.c)# 新增main所依赖的文件¥{MY_SOURCES}
add_executable(main main.c mouse_cursor_icon.c ${MY_SOURCES})
...
...

主函数main.c(调用自定义测试代码)

#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lvgl/examples/lv_examples.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "mycode/head.h"static const char *getenv_default(const char *name, const char *dflt)
{return getenv(name) ? : dflt;
}#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{const char *device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");lv_display_t * disp = lv_linux_fbdev_create();lv_linux_fbdev_set_file(disp, device);
}
#elif LV_USE_LINUX_DRM
static void lv_linux_disp_init(void)
{const char *device = getenv_default("LV_LINUX_DRM_CARD", "/dev/dri/card0");lv_display_t * disp = lv_linux_drm_create();lv_linux_drm_set_file(disp, device, -1);
}
#elif LV_USE_SDL
static void lv_linux_disp_init(void)
{const int width = atoi(getenv("LV_SDL_VIDEO_WIDTH") ? : "800");const int height = atoi(getenv("LV_SDL_VIDEO_HEIGHT") ? : "480");lv_sdl_window_create(width, height);
}
#else
#error Unsupported configuration
#endifvoid lv_touchpad_init(void)
{// 创建触摸屏设备,并关联到屏幕lv_indev_t *touchpad = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");lv_indev_set_disp(touchpad, lv_disp_get_default());
}int main(void)
{lv_init();/*Linux display device init*/lv_linux_disp_init();lv_touchpad_init();/*Create a Demo*/obj_test();/*Handle LVGL tasks*/while(1) {lv_timer_handler();usleep(5000);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/952948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSP-J2025 题解

拼数 思路 先考虑怎么把数字提取出来,可以拿一个字符串变量存储整个输入,然后遍历这个字符串,如果当前字符是 0 到 9 就可以通过将它减去 0 的方式放到一个整形数组中。 接下来考虑拼出最大的数,显然让这个数组从大…

CSP-S2025

流程是: T1-60pts -> T2-56pts -> T3-10pts -> T4-8pts -> T1-100pts

MySQL 慢查询日志slow query log - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年 11 月离心喷雾干燥机,振动流化床干燥机,带式干燥机厂家最新推荐,品牌深度解析采购无忧之选!

近期,行业权威协会针对离心喷雾干燥机、振动流化床干燥机、带式干燥机领域开展专项测评,通过对设备性能参数、生产企业技术实力、市场用户反馈等多维度数据采集分析,最终形成本次推荐榜单。测评过程中,不仅对设备的…

unity技巧备忘

在编辑器,检视面板 中执行代码 using UnityEngine; public class HighScore : MonoBehaviour { public bool resetHighScoreNow = false;private void OnDrawGizmos(){if (resetHighScoreNow){resetHighScoreNow …

前端开发技术栈

目录Nodejs参考资料 Nodejs 工具链: Node.js 是前端开发工具链的重要组成部分,例如用于构建工具、包管理器(如 npm)等,这些工具可以在本地开发环境中运行。 非直接开发: 虽然 Node.js 本身不直接属于前端,但它通…

SOA、ESB、微服务、分布式概念及专业名词阐述

SOA、ESB、微服务概念1 SOA 面向服务 SOA全称:Service Oriented Architecture,面向服务框架。它是一种设计理念,其中包含多个服务,服务之间通过相互依赖最终提供一系列完成的功能。各个服务通常以独立的形式部署运…

unity技巧

在编辑器,检视面板 中执行代码 using UnityEngine; public class HighScore : MonoBehaviour { public bool resetHighScoreNow = false;private void OnDrawGizmos(){if (resetHighScoreNow){resetHighScoreNow …

项目2:图书管理系统(数据库入门)

核心功能:添加图书(书名、作者、ISBN、出版年份) 搜索图书(按书名、作者) 更新图书信息 删除图书 获取图书统计(总数、按作者分组)技术栈:SQLModel数据库集成 基础查询和过滤 简单数据统计 错误处理挑战点:数…

CF2153B Bitwise Reversion | 数学 | 模拟

CF2153B Bitwise Reversion | 数学 | 模拟 题目描述 给定三个非负整数 \(x\),\(y\) 和 \(z\),判断是否存在三个非负整数 \(a\)、\(b\)、\(c\),满足以下三个条件:\(a \mathbin{\&} b = x\) \(b \mathbin{\&…

DRL-QLearning与DQN

强化学习领域中,Q-learning和深度Q网络(DQN)是两个具有里程碑意义的算法。Q-learning奠定了传统强化学习的基础,而DQN则开启了深度强化学习的新时代。本文将深入探讨这两种算法的核心概念和工作原理,帮助读者理解它…

2025 年 11 月真空耙式干燥机,高效沸腾干燥机,盘式干燥机厂家最新推荐,高性能,稳定性强的行业优选

近期,行业设备性能评估协会联合稳定性测试机构,针对真空耙式干燥机、高效沸腾干燥机、盘式干燥机领域,开展 “高性能 - 强稳定” 专项测评。高性能维度设定三项核心标准:干燥效率(比行业平均水平高 15% 以上)、能…

2025 年 11 月盘式干燥机,空心桨叶干燥机,振动流化床干燥机厂家最新推荐,技术实力与市场口碑深度解析

近期,行业技术评估协会联合市场调研机构,针对盘式干燥机、空心桨叶干燥机、振动流化床干燥机领域,开展 “技术实力 - 市场口碑” 双维度专项解析。技术实力测评涵盖三项核心指标:一是研发硬实力(研发团队规模≥15…

2025 年 11 月双锥回转真空干燥机,离心喷雾干燥机,带式干燥机厂家最新推荐,专业制造与品牌保障口碑之选

近期,行业制造标准协会联合品牌评估机构,针对双锥回转真空干燥机、离心喷雾干燥机、带式干燥机领域,开展 “专业制造 - 品牌保障” 双核心测评。专业制造维度从三方面评估:一是生产工艺专业性(是否采用行业专用生…

DRL-时序差分学习

时序差分(Temporal Difference, TD)学习是强化学习中的一种核心方法,它结合了动态规划和蒙特卡洛方法的优点,实现了无需环境模型的在线学习。本指南将详细介绍TD学习的原理。时序差分学习技术指南 时序差分(Tempo…

再见了ThreadLocal,我决定用ScopedValue!

前言 今天我们来聊聊一个即将改变我们编程习惯的新特性——ScopedValue。 有些小伙伴在工作中,一提到线程内数据传递就想到ThreadLocal,但真正用起来却遇到各种坑:内存泄漏、数据污染、性能问题等等。 其实,Scoped…

查询增强插件pgfincore - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年 11 月双锥回转真空干燥机,真空耙式干燥机,盘式干燥机厂家最新推荐,聚焦资质、案例、售后的六家机构深度解读

近期,十家行业权威机构联合开展双锥回转真空干燥机、真空耙式干燥机、盘式干燥机专项测评,通过资质审核、案例验证、售后调研三大核心维度,对近百家厂家进行综合评估。资质审核环节重点核查企业专利数量、体系认证(…

2025 年 11 月高效沸腾干燥机,旋转闪蒸干燥机,空心桨叶干燥机厂家最新推荐,产能、专利、环保三维数据透视

近期,行业协会联合专业测评机构,针对高效沸腾干燥机、旋转闪蒸干燥机、空心桨叶干燥机领域开展专项评估,从产能、专利、环保三大核心维度构建测评体系。产能维度重点核查企业年产能规模、生产线自动化程度及订单交付…