当前位置: 首页 > news >正文

01LVGL图形界面库

一、LVGL(Light and Versatile Graphics Library) 概念

欢迎阅读LVGL中文开发手册! — LVGL 文档 (中文翻译手册)

LVGL: Light and Versatile Graphics Library — LVGL documentation (官方手册)

GitHub - lvgl/lvgl: Embedded graphics library to create beautiful UIs for any MCU, MPU and display type. (源码官网)

LVGL 是最流行的免费开源嵌入式图形库,可以为任何 MCU、MPU 和显示类型创建漂亮的 UI。
它得到了行业领先供应商和项目的支持,如 Arm、STM32、NXP、Espressif、Nuvoton、Arduino、RT-Thread、Zephyr、NuttX、Adafruit 等。
功能丰富
它拥有创建现代美观 GUI 的所有功能:30 多个内置控件、强大的样式系统、Web 启发的布局管理器和支持多种语言的排版系统。
要将 LVGL 集成到您的平台中,您只需要至少 32 KB RAM 和 128 KB Flash、C 编译器、
帧缓冲区和至少 1/10 屏幕大小的渲染缓冲区。

功能介绍
强大的构建模块,例如
按钮、图表、列表、滑块、图像 等。
具有动画、抗锯齿、不透明度、平滑滚动的高级图形
各种输入设备,如触摸板、鼠标、键盘、编码器等
支持多语言,采用 UTF-8 编码
支持多显示器,甚至支持混合颜色格式
完全可定制的图形元素,具有类似 CSS 的样式
硬件无关:可与任何微控制器或显示器一起使用
可扩展:能够在内存较少的情况下运行(64 kB Flash,16 kB RAM)
支持但不要求
操作系统、外部内存和 GPU
即使使用高级图形效果也能进行单帧缓冲操作
用 C 语言编写,以实现最大兼容性(兼容 C++)
模拟器
 可在没有嵌入式硬件的 PC 上开始嵌入式 GUI 设计
在模拟器下开发的用户代码可以与固件共享,使 UI 开发更高效
绑定到
 MicroPython
教程、示例、主题,用于快速 GUI 设计
文档可在线获取
在 MIT 许可证下免费开源

二、LVGL 登神之路

Get started(开始) — LVGL 文档

1.下载LVGL 工程

配置文件

下载 lv_port_linux 配置文件 把 lvgl 文件夹放入该配置文件中即可使用!

GitHub - lvgl/lv_port_linux: LVGL configured to work with a standard Linux framebuffer

命令下载方式 git clone https://github.com/lvgl/lv_port_linux.git cd lv_port_linux/ git submodule update --init --recursive

提示:下载步骤不用操作知道如何下载即可。

直接使用下载好的源码包

2.升级WSL版本为 WSL2

旧版 WSL 的手动安装步骤 | Microsoft Learn 官方更新教程

更新WSL版本

C:\Users\Administrator>wsl  -l  -v           #查看当前的WSL 版本  
  NAME            STATE           VERSION
* Ubuntu-22.04    Stopped         1

C:\Users\Administrator>wsl   --set-default-version   2    #设置默认版本为 2 
有关与 WSL 2 关键区别的信息,请访问 https://aka.ms/wsl2

操作成功完成。

C:\Users\Administrator>wsl  --set-version  Ubuntu-22.04  2   #设置  ubuntu-22.04 版本为 2  
有关与 WSL 2 关键区别的信息,请访问 https://aka.ms/wsl2

正在进行转换,这可能需要几分钟时间。

C:\Users\Administrator>wsl  --update                         #更新WSL系统  
正在检查更新。
已安装最新版本的适用于 Linux 的 Windows 子系统。

成功如图

3.安装SDL库

sudo  apt-get  update                    #更新软件源  
sudo apt-get   install  libsdl2-dev      #安装SDL库 

成功如图

4.编译&运行模拟器

 tar  -xvf  lv_port_linux_ubuntu_sdl.tar.bz    -C   ~/   #解压源码到家目录 
 cd  ~/lv_port_linux/                                    #进入源码目录  
 make clean                                              #清空文件 
 make  -j12                                              #启动12个线程编译  
 ./build/bin/main                                        #运行例子程序 

显示如图界面则安装模拟器成功

 三、LVGL 工程分析

 main.c主函数

#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.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
#endif

int main(void)
{
    lv_init(); // 初始化LVGL库
    /*Linux display device init*/
    lv_linux_disp_init(); // 初始化显示器

    // init input device  初始化输入设备
    lv_sdl_mouse_create();      // 鼠标
    lv_sdl_keyboard_create();   // 键盘
    lv_sdl_mousewheel_create(); // 滚轮

    /*Create a Demo  创建示例*/
    // lv_example_button_1();
    // lv_demo_widgets();
    // lv_example_ime_pinyin_2();

    /*Handle LVGL tasks  处理lvgl任务*/
    while(1) {
        lv_timer_handler();
        usleep(5000);
    }
    return 0;
}

lv_conf.h 配置文件

注意注意注意:修改了lv_conf.h 配置文件后,必须要make clean ,再make 才能生效

/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)  设置像素点色深*/  
#define LV_COLOR_DEPTH 16   

/*API for fopen, fread, etc  设置文件IO读取盘符*/  
#define LV_USE_FS_STDIO 1
#if LV_USE_FS_STDIO
    #define LV_FS_STDIO_LETTER 'A'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    #define LV_FS_STDIO_PATH ""         /*Set the working directory. File/directory paths will be appended to it.*/
    #define LV_FS_STDIO_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
#endif


/*Use SDL to open window on PC and handle mouse and keyboard  配置SDL的显示框架*/
#define LV_USE_SDL              1


/*Driver for /dev/fb*/     配置linux 的显示框架
#define LV_USE_LINUX_FBDEV      0   

四、LVGL 基本对象概念

在LVGL 图形库中所有看见的东西都是一个 对象lv_obj_t * parent 每个对象都拥有,位置大小,事件 ... 等内容。

Base object(基础对象) (lv_obj) — LVGL 文档

//获取当前活跃的屏幕对象 
lv_obj_t * lv_screen_active(void)

//加载活跃的屏幕对象 
void lv_screen_load(struct _lv_obj_t * scr);

//创建一个对象 
lv_obj_t *lv_obj_create(lv_obj_t *parent)
parent:父亲对象,一个子对象都必须有一个父对象,否则该对象就是一个新的屏幕 
返回值:lv_obj_t *新的对象 

//删除对象
void lv_obj_delete(lv_obj_t *obj)  

//对象大小设置
lv_obj_set_width(obj, new_width)    设置宽度 
lv_obj_set_height(obj, new_height)  设置高度
lv_obj_set_size(obj, new_width, new_height)  设置宽度与高度 

//对象位置设置 
lv_obj_set_x(obj, new_x)    设置X轴坐标 
lv_obj_set_y(obj, new_y)    设置Y轴坐标  
lv_obj_set_pos(obj, new_x, new_y)  设置 X 与 Y 坐标 


//例子:在屏幕中创建一个对象  
lv_obj_t *screen = lv_screen_active();  
lv_obj_t *myobj =lv_obj_create(screen); 

对齐规则

/** Alignments*/

enum _lv_align_t {
    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_align(lv_obj_t *obj, lv_align_t align)    设置对齐位置  
void lv_obj_align(lv_obj_t *obj, lv_align_t align, int32_t x_ofs, int32_t y_ofs)  ✔️设置对齐位置和偏移量 
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)  ✔️根据base参考位置设置对齐
obj:需要设置的对象 
base:参考位置
align:对齐规则  
x_ofs:x 轴偏移量 
y_ofs:y 轴偏移量 


void lv_obj_center(lv_obj_t *obj)  快速放置中央

父子结构

一个父对象可以被视为其子对象的容器。每个对象都都必须会有且仅有一个父对象(屏幕除外),但一个父对象可以有任意数量的子对象。

lv_obj_t * parent = lv_obj_create(lv_screen_active());   /* 在当前屏幕上创建一个父对象 */
lv_obj_set_size(parent, 100, 80);                    /* 设置父对象的大小 */

lv_obj_t * obj1 = lv_obj_create(parent);             /* 在先前创建的父对象上创建一个对象 */
lv_obj_set_pos(obj1, 10, 10);                        /* 设置新对象的位置 */


lv_obj_set_parent(obj, new_parent)   :设置一个父亲对象 
lv_obj_get_child(parent, idx)       :获取当前的孩子对象
lv_obj_t *lv_obj_get_parent(const lv_obj_t *obj)  :获取当前父亲对象 
uint32_t lv_obj_get_child_count(const lv_obj_t *obj) :获取孩子数 

demo父子对象操作

 lv_obj_t * parent = lv_obj_create(lv_screen_active());
    lv_obj_set_size(parent, 300, 300);
    lv_obj_center(parent);

    lv_obj_t * obj = lv_obj_create(lv_screen_active());
    lv_obj_set_pos(obj, 100, 0);
    lv_obj_t * obj1 = lv_obj_create(lv_screen_active());
    lv_obj_set_pos(obj1, 200, 0);
    lv_obj_t * obj2 = lv_obj_create(lv_screen_active());
    lv_obj_set_pos(obj2, 300, 0);

    // 设置一个父亲对象
    lv_obj_set_parent(obj, parent);
    lv_obj_set_parent(obj1, parent);
    lv_obj_set_parent(obj2, parent);
    //获取当前父亲对象的孩子数
    int child_count = lv_obj_get_child_count(parent);
    printf("child_count=%d\n", child_count);
    //打印对象地址
    printf("obj= %p\n", obj);
    printf("obj1= %p\n", obj1);
    printf("obj2= %p\n", obj2);
   //获取子对象的地址 
    for(int i = 0; i < child_count; i++) {
        printf("child=%p\n", lv_obj_get_child(parent, i));
    }

至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见

相关文章:

  • Tauri + Vite + SvelteKit + TypeScript 跨平台开发全流程指南(Linux)
  • FANformer:融合傅里叶分析网络的大语言模型基础架构
  • 【C语言】memset(含常见用途、注意事项)
  • AWS Bedrock 正式接入 DeepSeek-R1 模型:安全托管的生成式 AI 解决方案
  • 2025年【A特种设备相关管理】免费试题及A特种设备相关管理模拟考试题库
  • 哪些业务场景更适合用MongoDB?何时比MySQL/PostgreSQL好用?
  • JavaScript性能优化
  • HTML基础
  • 深度学习实验
  • upload-labs-master通关攻略(1~4)
  • Linux内核如何和设备树协同工作的?
  • Oracle中Unique(id)和id int unique的区别
  • Redis常用数据结构及命令详解:从基础到进阶
  • Qt Creator插件系统详解及插件开发实战
  • 【后端】【ubuntu】 ubuntu目录权限查看的几种方法
  • 《旅游与摄影》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • 【脚本】Linux一键扩大虚拟内存的大小
  • 多光谱相机数据采集过程中常见仪器
  • 基于FPGA的图像退化算法verilog实现,分别实现横向和纵向运动模糊,包括tb和MATLAB辅助验证
  • ARM SVC指令
  • 专门做广东11选5的网站/软文代写接单平台
  • 做网站买什么服务器 便宜/西安关键词排名软件
  • 绵阳建网站/电脑编程培训学校
  • 外贸网站建设及优化ppt模块/百度指数分析官网
  • 做网站的基本知识/seo的研究对象
  • 西宁做网站君博相约/最新网络营销方式有哪些