lvgl/lvgl

GitHub: lvgl/lvgl

一款轻量级开源嵌入式图形库,为资源受限的 MCU/MPU 提供丰富控件和现代 UI 能力。

Stars: 22876 | Forks: 4055

English | 中文 | Português do Brasil | 日本語 | עברית


 

轻量级通用图形库


   

网站 | LVGL Pro 编辑器 | 文档 | 论坛 | 演示 | 服务


### 目录

概述
功能特性
平台支持
LVGL Pro 编辑器
商业服务
集成 LVGL
示例
贡献


## 📒 概述 **LVGL** 是一个免费且开源的 UI 库,让你能够为任何厂商、任何平台上的 MCU 和 MPU 创建图形用户界面。 **需求**:LVGL 没有外部依赖,这使得它很容易编译到任何现代目标平台,从小型 MCU 到支持 3D 的多核 Linux MPU。对于一个简单的 UI,你只需要约 100kB RAM、约 200–300kB Flash,以及 1/10 屏幕大小的缓冲区用于渲染。 **入门指南**:选择一个现成的 VSCode、Eclipse 或其他项目,并在你的 PC 上试用 LVGL。LVGL 的 UI 代码完全独立于平台,因此你同样可以在嵌入式目标上使用相同的 UI 代码。 **LVGL Pro** 是一个完整的工具包,帮助你更快地构建、测试、共享和发布 UI。它附带一个 XML 编辑器,你可以在其中快速创建和测试可复用组件,导出 C 代码,或在运行时加载 XML。在此了解更多。 ## 💡 功能特性 **免费且可移植** - 一个完全可移植的 C(兼容 C++)库,没有外部依赖。 - 可以编译到任何 MCU 或 MPU,配合任何 操作系统。支持 Make、CMake 和简单的文件通配。 - 支持单色、电子墨水、OLED 或 TFT 显示屏,甚至是显示器。[Displays](https://docs.lvgl.io/master/main-modules/display/index.html) - 在 MIT 许可下分发,因此你也可以轻松地在商业项目中使用它。 - 仅需 32kB RAM 和 128kB Flash,一个帧缓冲区,以及至少 1/10 屏幕大小的缓冲区用于渲染。 - 支持 但不依赖 OS、外部内存和 GPU。 **组件、样式、布局等** - 30+ 内置 [Widgets](https://docs.lvgl.io/master/widgets/index.html):按钮、标签、滑块、图表、键盘、仪表、弧线、表格等。 - 灵活的 [Style system](https://docs.lvgl.io/master/common-widget-features/styles/index.html),拥有约 100 种样式属性,可以在任何状态下自定义组件的任何部分。 - 类似 [Flexbox](https://docs.lvgl.io/master/common-widget-features/layouts/flex.html) 和 [Grid](https://docs.lvgl.io/master/common-widget-features/layouts/grid.html) 的布局引擎,可响应式地自动调整组件的大小和位置。 - 文本采用 UTF-8 编码渲染,支持 CJK、泰语、印地语、阿拉伯语和波斯语书写系统。 - [Data bindings](https://docs.lvgl.io/master/main-modules/observer/index.html) 可轻松将 UI 与应用程序连接。 - 渲染引擎支持动画、抗锯齿、不透明度、平滑滚动、阴影、图像变换等。 - [Powerful 3D rendering engine](https://docs.lvgl.io/master/libs/gltf.html) 可通过 OpenGL 显示 [glTF models](https://sketchfab.com/)。 - 支持鼠标、触摸板、小键盘、键盘、外部按钮、编码器 [Input devices](https://docs.lvgl.io/master/main-modules/indev.html)。 - 支持 [Multiple display](https://docs.lvgl.io/master/main-modules/display/overview.html#how-many-displays-can-lvgl-use)。 ## 📦️ 平台支持 LVGL 没有外部依赖,因此可以轻松地为任何设备编译,并且它也可在许多包管理器和 RTOS 中使用: - [Arduino library](https://docs.lvgl.io/master/integration/framework/arduino.html) - [PlatformIO package](https://registry.platformio.org/libraries/lvgl/lvgl) - [Zephyr library](https://docs.lvgl.io/master/integration/os/zephyr.html) - [ESP-IDF(ESP32) component](https://components.espressif.com/components/lvgl/lvgl) - [NXP MCUXpresso component](https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY) - [NuttX library](https://docs.lvgl.io/master/integration/os/nuttx.html) - [RT-Thread RTOS](https://docs.lvgl.io/master/integration/os/rt-thread.html) - CMSIS-Pack - [RIOT OS package](https://doc.riot-os.org/group__pkg__lvgl.html#details) ## 🚀 LVGL Pro 编辑器 LVGL Pro 是一个完整的工具包,用于高效地构建、测试、共享和交付嵌入式 UI。 它由四个紧密相关的工具组成: 1. **XML 编辑器**:LVGL Pro 的核心。这是一个桌面应用程序,用于在 XML 中构建组件和屏幕,管理数据绑定、翻译、动画、测试等。在 [XML Format](https://docs.lvgl.io/master/xml/xml/index.html) 和 [Editor](https://docs.lvgl.io/master/xml/editor/index.html) 中了解更多。 2. **在线查看器**:在浏览器中运行编辑器,打开 GitHub 项目,无需设置开发环境即可轻松共享。访问 [https://viewer.lvgl.io](https://viewer.lvgl.io)。 3. **CLI 工具**:在 CI/CD 中生成 C 代码并运行测试。在 [此处](https://docs.lvgl.io/master/xml/tools/cli.html) 查看详情。 4. **Figma 插件**:直接从 Figma 同步和提取样式。在 [此处](https://docs.lvgl.io/master/xml/tools/figma.html) 查看其工作原理。 这些工具共同让开发者能够高效地构建 UI,可靠地测试它们,并与团队成员和客户协作。 在 https://pro.lvgl.io 了解更多 ## 🤝 商业服务 LVGL LLC 提供多种类型的商业服务来协助你进行 UI 开发。凭借在用户界面和图形行业 15 年以上的经验,我们可以帮助你将 UI 提升到一个新的水平。 - **图形设计**:我们的内部平面设计师擅长创作符合你的产品及硬件能力的精美现代设计。 - **UI 实现**:我们可以根据你或我们创建的设计来实现你的 UI。你可以确信我们将充分利用你的硬件和 LVGL。如果 LVGL 缺少某项功能或组件,别担心,我们会为你实现它。 - **咨询与支持**:我们还提供咨询服务,帮助你在 UI 开发过程中避免昂贵且耗时的错误。 - **开发板认证**:对于提供开发板或量产套件的公司,我们提供开发板认证,以展示该开发板如何运行 LVGL。 查看我们的 [Demos](https://lvgl.io/demos) 作为参考。欲了解更多信息,请查看 [Services page](https://lvgl.io/services)。 [联系我们](https://lvgl.io/#contact) 并告诉我们如何为你提供帮助。 ## 🧑‍💻 集成 LVGL 集成 LVGL 非常简单。只需将其放入任何项目中,并像编译其他文件一样编译它即可。 要配置 LVGL,请将 `lv_conf_template.h` 复制为 `lv_conf.h`,启用第一个 `#if 0`,并根据需要调整配置。(默认配置通常就很好。)如果可用,LVGL 也可以与 Kconfig 一起使用。 进入项目后,你可以按如下方式初始化 LVGL 并创建显示和输入设备: ``` #include "lvgl/lvgl.h" /*Define LV_LVGL_H_INCLUDE_SIMPLE to include as "lvgl.h"*/ #define TFT_HOR_RES 320 #define TFT_VER_RES 240 static uint32_t my_tick_cb(void) { return my_get_millisec(); } static void my_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) { /*Write px_map to the area->x1, area->x2, area->y1, area->y2 area of the *frame buffer or external display controller. */ /* signal LVGL that we're done */ lv_display_flush_ready(disp); } static void my_touch_read_cb(lv_indev_t * indev, lv_indev_data_t * data) { if(my_touch_is_pressed()) { data->point.x = touchpad_x; data->point.y = touchpad_y; data->state = LV_INDEV_STATE_PRESSED; } else { data->state = LV_INDEV_STATE_RELEASED; } } void main(void) { my_hardware_init(); /*Initialize LVGL*/ lv_init(); /*Set millisecond-based tick source for LVGL so that it can track time.*/ lv_tick_set_cb(my_tick_cb); /*Create a display where screens and widgets can be added*/ lv_display_t * display = lv_display_create(TFT_HOR_RES, TFT_VER_RES); /*Add rendering buffers to the screen. *Here adding a smaller partial buffer assuming 16-bit (RGB565 color format)*/ static uint8_t buf[TFT_HOR_RES * TFT_VER_RES / 10 * 2]; /* x2 because of 16-bit color depth */ lv_display_set_buffers(display, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Add a callback that can flush the content from `buf` when it has been rendered*/ lv_display_set_flush_cb(display, my_flush_cb); /*Create an input device for touch handling*/ lv_indev_t * indev = lv_indev_create(); lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); lv_indev_set_read_cb(indev, my_touch_read_cb); /*The drivers are in place; now we can create the UI*/ lv_obj_t * label = lv_label_create(lv_screen_active()); lv_label_set_text(label, "Hello world"); lv_obj_center(label); /*Execute the LVGL-related tasks in a loop*/ while(1) { lv_timer_handler(); my_sleep_ms(5); /*Wait a little to let the system breathe*/ } } ``` ## 🤖 示例 你可以在 https://docs.lvgl.io/master/examples.html 查看超过 100 个示例 在线查看器还包含轻松学习 XML 的教程:https://viewer.lvgl.io/ ### 带事件的 Hello World 按钮 image
C 代码 ``` static void button_clicked_cb(lv_event_t * e) { printf("Clicked\n"); } [...] lv_obj_t * button = lv_button_create(lv_screen_active()); lv_obj_center(button); lv_obj_add_event_cb(button, button_clicked_cb, LV_EVENT_CLICKED, NULL); lv_obj_t * label = lv_label_create(button); lv_label_set_text(label, "Hello from LVGL!"); ```
使用 LVGL Pro 的 XML ``` ```
### 带数据绑定的样式化滑块 image
C 代码 ``` static void my_observer_cb(lv_observer_t * observer, lv_subject_t * subject) { printf("Slider value: %d\n", lv_subject_get_int(subject)); } [...] static lv_subject_t subject_value; lv_subject_init_int(&subject_value, 35); lv_subject_add_observer(&subject_value, my_observer_cb, NULL); lv_style_t style_base; lv_style_init(&style_base); lv_style_set_bg_color(&style_base, lv_color_hex(0xff8800)); lv_style_set_bg_opa(&style_base, 255); lv_style_set_radius(&style_base, 4); lv_obj_t * slider = lv_slider_create(lv_screen_active()); lv_obj_center(slider); lv_obj_set_size(slider, lv_pct(80), 16); lv_obj_add_style(slider, &style_base, LV_PART_INDICATOR); lv_obj_add_style(slider, &style_base, LV_PART_KNOB); lv_obj_add_style(slider, &style_base, 0); lv_obj_set_style_bg_opa(slider, LV_OPA_50, 0); lv_obj_set_style_border_width(slider, 3, LV_PART_KNOB); lv_obj_set_style_border_color(slider, lv_color_hex3(0xfff), LV_PART_KNOB); lv_slider_bind_value(slider, &subject_value); lv_obj_t * label = lv_label_create(lv_screen_active()); lv_obj_align(label, LV_ALIGN_CENTER, 0, -30); lv_label_bind_text(label, &subject_value, "Temperature: %d °C"); ```
使用 LVGL Pro 的 XML ```