试用 LVGL Pro,一套完整的工具包,助您高效构建、测试、分享和交付 UI!
LVGL
公告

LVGL MicroPython 绑定 - 嵌入式 Python 的高级 GUI

介绍 LVGL 的官方 MicroPython 绑定,让 Python 开发者能够使用交互式开发和面向对象设计模式来创建嵌入式图形界面。

Amir GonnenAmir Gonnen18 分钟阅读
LVGL + MicroPython 标志
LVGL + MicroPython 标志

什么是 MicroPython?#

MicroPython 是面向微控制器的 Python。使用 MicroPython,您可以编写 Python 3 代码并在资源有限的裸机架构上运行。

MicroPython 的亮点#

  • 紧凑 - 仅需 256k 代码空间和 16k 内存即可运行。不需要操作系统,当然您也可以在操作系统上运行它。
  • 兼容 - 力求与标准 Python(称为 CPython)尽可能兼容。
  • 多功能 - 支持多种架构(x86、x86-64、ARM、ARM Thumb、Xtensa)。
  • 交互式 - 无需编译-烧写-启动循环。使用 REPL(交互式提示符),您可以输入命令并立即执行,运行脚本等。
  • 流行 - 支持众多平台。用户群体不断扩大。著名的分支包括 MicroPythonCircuitPythonMicroPython_ESP32_psRAM_LoBo
  • 嵌入式导向 - 专门为嵌入式系统提供模块,如用于访问低级硬件(I/O 引脚、ADC、UART、SPI、I2C、RTC、定时器等)的 machine 模块

为什么选择 MicroPython + LVGL?#

目前 MicroPython 没有一个好的高级 GUI 库。LVGL 是一个用 C 实现、提供 C API 的优秀高级 GUI 库。LVGL 是一个面向对象、基于组件的库,这使得它非常适合映射到像 Python 这样的高级语言。

在 MicroPython 中使用 LVGL 的优势#

  • 用 Python 开发 GUI - 使用一种非常流行的高级语言,支持面向对象编程等范式。
  • 快速迭代周期 - 使用 C 时,每次迭代包括修改代码 → 构建 → 烧写 → 运行。在 MicroPython 中,只需修改代码 → 运行。您甚至可以使用 REPL(交互式提示符)交互式地运行命令。

MicroPython + LVGL 的使用场景#

  • 快速 GUI 原型设计 - 快速尝试不同的设计和布局。
  • 缩短开发周期 - 无需编译/烧写开销即可修改和微调 GUI。
  • 抽象 GUI 建模 - 定义可重用的复合对象,利用 Python 的语言特性,如继承、闭包、列表推导、生成器、异常处理、任意精度整数等。
  • 更广泛的可访问性 - 使 LVGL 能够被更多受众使用。无需了解 C 即可在嵌入式系统上创建精美的 GUI。这与 CircuitPython 的愿景非常契合,CircuitPython 设计时就考虑到教育,让新手或没有经验的用户更容易开始嵌入式开发。

那么它看起来是什么样的?#

提示

它与 C API 非常相似,但 LVGL 组件采用面向对象的方式。

让我们直接看一个示例!

一个简单的示例#

import lvgl as lv
lv.init()
scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
lv.scr_load(scr)
python

在这个示例中,我们创建了一个按钮,将其居中对齐,并在上面添加了一个文本标签"Button"。最后,我们加载带有按钮的屏幕以显示它。

一个更高级的示例#

在这个示例中,我假设您已经具备一些 LVGL 的基础知识。如果没有,请快速浏览一下 LVGL 教程

class SymbolButton(lv.btn):
    def __init__(self, parent, symbol, text):
        super().__init__(parent)
        self.symbol = lv.label(self)
        self.symbol.set_text(symbol)
        self.symbol.set_style(symbolstyle)
 
        self.label = lv.label(self)
        self.label.set_text(text)
python

在这个示例中,我们创建了一个名为 SymbolButton可重用复合组件。它是一个类,因此我们可以从它创建对象实例。它是复合的,因为它由多个原生 LVGL 对象组成:

  • 一个按钮 - SymbolButton 继承自 lv.btnlv.btn 是一个原生 LVGL 按钮组件。
  • 一个符号标签 - 一个具有符号样式(符号字体)的标签,作为 self 的子对象(即 SymbolButton 继承的父按钮的子对象)。lv.label 是一个原生 LVGL 标签组件,表示另一个组件内的文本。
  • 一个文本标签 - 一个带有文本的标签,作为 self 的另一个子对象。

SymbolButton 构造函数(__init__ 函数)创建了这两个标签,并设置了它们的内容和样式。

以下是如何使用我们的 SymbolButton 的示例:

self.btn1 = SymbolButton(page, lv.SYMBOL.PLAY, "Play")
self.btn1.set_size(140,100)
self.btn1.align(None, lv.ALIGN.IN_TOP_LEFT, 10, 0)
 
self.btn2 = SymbolButton(page, lv.SYMBOL.PAUSE, "Pause")
self.btn2.set_size(140,100)
self.btn2.align(self.btn1, lv.ALIGN.OUT_RIGHT_TOP, 10, 0)
python

这里,我们设置了每个按钮的大小,将 btn1 对齐到页面,并将 btn2 相对于 btn1 对齐。我们调用了复合组件 SymbolButtonset_sizealign 方法——这些方法是从 SymbolButton 的父类 lv.btn 继承的,lv.btn 是一个 LVGL 原生对象。

结果如下所示:

播放和暂停按钮示例
播放和暂停按钮示例

要获取更完整的示例(包括其他对象类型以及动作回调函数和驱动程序注册),请查看这个演示脚本

以下是在 MicroPython 中使用 LVGL 的更多示例:

创建带有按钮和标签的屏幕#

scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
 
# 加载屏幕
lv.scr_load(scr)
python

创建结构体实例#

symbolstyle = lv.style_t(lv.style_plain)
python

symbolstyle 将是一个 lv_style_t 的实例,初始化为与 lv_style_plain 相同的值。

设置结构体中的字段#

symbolstyle.text.color = lv.color_hex(0xffffff)
python

symbolstyle.text.color 将被初始化为 lv_color_hex 返回的颜色结构体。

使用字典设置嵌套结构体#

symbolstyle.text.color = {"red":0xff, "green":0xff, "blue":0xff}
python

创建对象实例#

self.tabview = lv.tabview(lv.scr_act())
python

对象构造函数的第一个参数是父对象,第二个参数是要从哪个元素复制此元素。

调用对象方法#

self.symbol.align(self, lv.ALIGN.CENTER, 0, 0)
python

在这个示例中,lv.ALIGN 是一个枚举,lv.ALIGN.CENTER 是一个枚举成员(一个整数值)。

使用回调函数#

for btn, name in [(self.btn1, 'Play'), (self.btn2, 'Pause')]:
    btn.set_action(lv.btn.ACTION.CLICK, lambda action,name=name: self.label.set_text('%s click' % name) or lv.RES.OK)
python

这里,我们有一个循环,为按钮 btn1btn2 设置动作。btn1 的动作是将 label 文本设置为"Play click",btn2 的动作是将 label 文本设置为"Pause click"。

这是如何工作的?首先您需要理解两个 Python 特性:lambda闭包set_action 函数需要两个参数:一个动作枚举(在本例中为 CLICK)和一个函数。在 Python 中,函数是"一等公民",这意味着它们可以被当作值并传递给另一个函数,就像这个例子中一样。

我们传递的函数是一个 lambda,这是一个匿名函数。它的第一个参数是动作,第二个参数是来自 for 循环的 name 变量。该函数不使用 action 参数,但使用 name 来设置标签的文本。

设置完标签文本后,lambda 函数完成并返回 lv.RES.OK 值。lambda 不能有 return 语句,因为它必须是一个表达式。set_text 的求值结果为 None,因此 set_text(...) or lv.RES.OK 的求值结果为 lv.RES.OK,并被视为 lambda 函数的返回值。

您可能会问自己——为什么我们需要将 name 作为参数传递?为什么不像这样在 lambda 中直接使用它:lambda action: self.label.set_text('%s click' % name)

嗯,**这样做不会正确工作!**像这样使用 name 会创建一个闭包,这是一个记住封闭作用域中值(在本例中为 name)的函数对象。问题在于,在 Python 中,name 的解析是在执行 name 时完成的。如果我们将 name 放在 lambda 函数中,就太晚了——name 已经被设置为 Pause,因此两个按钮都会设置"Pause click"文本。我们需要在 for 循环迭代执行时设置 name,而不是在执行 lambda 函数时。因此我们将 name 作为参数传递,这是它被解析的时刻。这里有一篇简短的 Stack Overflow 帖子解释了这一点。

查看完整脚本

提示

目前绑定限制为每个对象只能有一个回调函数。


它是如何工作的?#

提示

一个脚本解析 LVGL 头文件并创建 MicroPython 模块。

要在 MicroPython 中使用 LVGL,您需要 MicroPython Binding for LVGL。此绑定是 LVGL MicroPython 模块的生成器。它本质上是一个 Python 脚本,读取并解析 LVGL C 头文件,然后从中生成 MicroPython 模块。该模块可以在 MicroPython 中用于访问大部分 LVGL API。

LVGL 是一个面向对象、基于组件的库。有一个名为 lv_obj 的基类,所有其他组件都从它继承,在组件之间创建了一个层次结构。对象有它们的方法函数,继承它们父类的方法等。MicroPython Binding for LVGL 利用了这种设计,并在 Python 中对此类层次结构进行建模。您可以通过继承从现有 LVGL 组件创建自己的(纯 Python)复合组件。

有关更多详细信息,请参阅 MicroPython Binding for LVGL 的 README


如何使用它?#

快速入门

最快的开始方式:Fork lv_micropython。它包含 MicroPython + LVGL 的可用 Unix(Linux)和 ESP32 移植。

MicroPython Binding for LVGLlv_binding_micropython)旨在简化在 MicroPython 中使用 LVGL。原则上它可以支持任何 MicroPython 分支。

要将它添加到某个 MicroPython 分支,您需要在 MicroPython lib 下将 lv_binding_micropython 添加为 git 子模块。lv_binding_micropython 本身包含 LVGL 作为 git 子模块。在 MicroPython 代码本身中,只需要进行很少的更改。您需要在 MicroPython Makefile 中添加一些行来创建 LVGL 绑定模块并编译 LVGL,并且还需要通过编辑 mpconfigport.h 将新的 lvgl 模块添加到 MicroPython。

作为示例,我创建了 lv_micropython——一个带有 LVGL 绑定的 MicroPython 分支。您可以按原样使用它,或者将其作为如何将 LVGL 与 MicroPython 集成的示例。lv_micropython 目前可以在 unix 移植和 ESP32 移植上与 LVGL 一起使用。

可用的驱动程序#

LVGL 需要显示屏和输入设备的驱动程序。MicroPython 绑定包含一些示例驱动程序,这些驱动程序在 lv_micropython 上注册和使用:

  • SDL unix 驱动程序(显示屏和鼠标)
  • ILI9341 驱动程序(用于 ESP32)
  • 原始电阻式触摸(用于 ESP32,ADC 直接连接到屏幕,无触摸 IC)

为其他显示屏和输入设备创建新驱动程序很容易。如果您添加了新驱动程序,我们很乐意将其添加到 MicroPython Binding,所以请向我们发送 pull request!


常见问题#

如何知道 MicroPython 中有哪些 LVGL 对象和函数可用?#

几乎所有的都可用!如果缺少某些您需要的功能,请在 MicroPython Binding Issues 部分打开一个 issue,我们会尝试添加它们。

  • 运行启用了 LVGL 模块的 MicroPython(例如 lv_micropython
  • 打开 REPL(交互式控制台)
  • import lvgl as lv
  • 输入 lv. + TAB 进行自动补全。将显示 LVGL 所有支持的类和函数。
  • 另一个选项:help(lv)
  • 另一个选项:print('\n'.join(dir(lv)))
  • 您也可以递归地执行此操作。例如 lv.btn. + TAB,或 print('\n'.join(dir(lv.btn)))

您还可以查看 LVGL 绑定模块本身。它在 MicroPython 构建期间生成,通常称为 lv_mpy.c

这是一个庞大的 API!仅 LVGL 绑定模块就有超过 25K 行代码!这还没算 LVGL 代码本身!#

这取决于 LVGL 配置。它可以很小也可以很大。请记住,LVGL 绑定模块是在您构建 MicroPython 时生成的,基于 LVGL 头文件和配置文件 - lv_conf.h。如果您在 lv_conf.h 中启用了所有内容——模块将会很大。您可以通过更改 lv_conf.h 中的定义来禁用功能并删除不需要的组件,模块将变得小得多。

无论如何,请记住该模块位于程序内存中。它本身不消耗 RAM,只消耗 ROM。从 RAM 的角度来看,LVGL 对象的每个实例通常只会消耗额外的几个字节,以表示 LVGL 对象周围的 MicroPython 包装器对象。

我想试试!最快的开始方式是什么?#

最快的开始方式:Fork lv_micropython。它包含 MicroPython + LVGL 的可用 unix(Linux)和 ESP32 移植。

Python 上的 LVGL?这不是有点......慢吗?#

不慢。所有 LVGL 功能(如渲染图形)仍然在 C 中执行。MicroPython 绑定只为 LVGL API 提供包装器,例如创建组件、设置它们的属性、布局、样式等。与其他 LVGL 功能相比,花费在这些操作上的周期非常少。

我可以在 XXXX MicroPython 分支上使用 LVGL 绑定吗?#

很可能可以!您需要将 MicroPython Binding for LVGL 作为子模块添加到您的分支中,并对 Makefile 和您的移植中的 mpconfigport.h 进行一些小的更改,但仅此而已。有关更多详细信息,请查看 README

我可以在 XXXX 显示屏/输入设备硬件上使用 LVGL 绑定吗?#

可以,但您需要驱动程序。LVGL 需要显示屏和输入设备的驱动程序。一旦您的硬件有了 C 驱动程序,将其包装为 MicroPython 中的模块并与 LVGL Binding for MicroPython 一起使用就非常简单了。您可以在 LVGL Binding for MicroPython 的 driver 目录中看到一些此类驱动程序(及其包装器 MicroPython 模块)的示例。

我需要分配一个 LVGL 结构体(如 Style、Color 等)。我该怎么做?如何为其分配/释放内存?#

在大多数情况下,您不需要担心内存分配。这是因为 LVGL 可以利用 MicroPython 的 gc(垃圾回收)。当内存被分配时,MicroPython 会知道何时在不再需要时释放它。

LVGL 结构体在 lvgl 模块下作为 MicroPython 类实现。您可以像创建任何其他对象一样创建它们:

import lvgl as lv
s = lv.style_t()
python

您还可以创建一个结构体,它是另一个结构体的副本:

import lvgl as lv
s = lv.style_t(lv.style_plain)
python

您可以像 C 结构体一样访问它们,使用 Python 属性:

s.text.color = lv.color_hex(0xffffff)
python

MicroPython 上的 LVGL 有些东西出错了/无法工作/缺失!#

请在 GitHub 上 MicroPython Binding for LVGLMicroPython Binding Issues 部分报告错误和问题。您也可以在 LVGL 论坛上联系我们以提问或进行任何其他讨论。

关于作者

Amir Gonnen
Amir Gonnen

社区贡献者

LVGL MicroPython 绑定的开发者和维护者,使嵌入式设备上的 Python UI 开发成为可能。

认识博客背后的作者们

了解那些分享 LVGL 知识的优秀作者们

查看作者

订阅我们的通讯 不错过任何关于 LVGL 的新闻。我们每月最多发送 2 封邮件。

LVGL

LVGL 是最受欢迎的免费开源嵌入式图形库,支持任何 MCU、MPU 和显示类型,助您构建精美的用户界面。

我们还提供 UI 设计、实现和咨询等服务。

© 2026 LVGL。保留所有权利。
YouTubeGitHubLinkedIn