【88掌控日】体验魔法画布——LVGL 实战开发与技巧(上)

W-Can1425 Lv3

说在前面

我的博客又有两三个月没更新了,其实与其说是不想更,不如说是没什么好更的。

不过夏天来了就是不一样。

我和我们团队很有幸接触到了掌控板的产品方 Labplus。本文我估计也就是对我昨日的直播的一个总结,留给我讲闲话的篇幅好像还比较多,不如我就在此简要提一嘴我是如何接触到产品方团队的吧。

5月14日11点45分(不是开玩笑,真在这个点发的),盛思科教 微信公众号发了一篇文章,名为《老开发深夜坦白局:“你知道这些年我怎么过的吗?!”——掌控板3.0开发故事汇》。这篇文章讲了些什么并不重要,重要的是在结尾有一个抽奖活动。我顺利的参与了抽奖并且联系到了产品方公众号的负责人。最终当然是我拿到了全新的掌控板,产品方也认识到了我们,皆大欢喜(^///^)

拿到板子后,我们迅速开始研究,至于成果,详见上一篇文章。产品方还邀请我们做客 88掌控日,活动也顺利的在 6月1日 成功举行。

本文所写内容,主要是对我在这场直播中所讲的关于 LVGL 在掌控板上的开发与应用做一个文字阐述和总结(说简单点就是我直播所讲的文字稿),希望这篇文章能给予你些许帮助。

关于本文

上面也说了,本文即 对我在这场直播中所讲的关于 LVGL 在掌控板上的开发与应用做一个文字阐述和总结。

在实际直播中,我通过案例的形式,与大家共同阅读分析代码,共同解决问题,旨在让每一位做客直播间的小伙伴都能从我并不充分的分享中收获些许有用的知识,至少能当在他们拿到 掌控板3.0 时知道可以做些什么。

我不知道我的分享是否达到了我的目的,但事已至此,多说无益。本文也将在大体上遵循我直播时所讲内容的结构组织文字。

案例一:掌控英语单词本(图形化)

为了照顾部分使用 mPython 软件图形化编程的小伙伴,我特意准备了这个简单的图形化案例,帮助各位小伙伴快速上手。

概览

  • 该案例原型灵感来自《构建您的第一个 Flutter 应用》

  • 你将学到什么:
    1.对 图形化编程下使用 LVGL 有一个基本了解
    2.掌握三个基础控件(矩形、文本框、按钮)的使用
    3.关联用户互动(如按下按钮)
    4.列表相关操作
    5.实战解决简单问题的能力
    6.让代码井然有序

  • 实现效果:
    实现效果

实现应用顶栏

应用顶栏,即位于应用或屏幕顶部的界面组件。在我们的日常生活中,不论是移动设备还是桌面设备上,该组件随处可见。

在 Android 开发中,创建一个应用顶栏很简单:

1
actionBar = getSupportActionBar();

当然,在其他现代化的应用开发平台/框架上,创建这类组件的操作都很简单。

但是在掌控板所使用的 LVGL 上,其并未直接实现该类组件。显然我们需要基于现有组件进行构造。

在开始之前,我们先认识一下我们即将要使用的图形化代码块:

显示文本
绘制矩形

一些过去使用过掌控板进行开发的小伙伴一眼应该就会看出猫腻,相对于 1.0/2.0 时期的代码块,其最大的变化就是多出了后面关于 显示颜色 的一些参数。

掌控板3.0 采用了一块 1.47寸高清 LCD 彩屏,它的分辨率:172x320。因此在此加入关于 显示颜色 方面的参数的确理所应当。

目前看起来除了这个变化,至少在图形化上看起来没有什么大的改动。

打开 mPython 软件,关于新版软件的介绍我写在了《掌控板3.0 体验前瞻报告》 中,这里就不再赘述。编写代码:

代码展示

有些同学可能会疑惑 设置屏幕颜色屏幕 显示清空 代码块有什么区别,经测试,两者的实际意义差别不大,都会覆盖掉屏幕上原有的内容,各位可以根据实际情况自行取舍。

第二个问题是为什么我在 显示文本 代码块中所给的纵坐标的值是 -3 而不是 0 ,这点是来自掌控板3.0 上针对 LVGL 的二次封装库 lv_gui.py 的一个特性。掌控板3.0 的屏幕圆角弧度变大了,可能是产品方的开发团队为了避免各位绘制在屏幕上的组件被屏幕圆角遮挡住,当你把此处纵坐标的值设置为 0 时,其在观感上更靠下了。所以此处我们做了一些细微调整。

最后与 1.0/2.0 如出一辙的是不要忘记加上 屏幕 显示生效 代码块。

实现单词显示

开始之前,先认识一个全新的组件:文本框

文本框

这里的使用方法所见即所得,此处不赘述,如果需要更详细的解读,请移步直播回放的 33:20 处。

需要特别强调的是,此处用于定义文本框的变量的名称不能相同(除非你就是为了覆盖某个已创建的文本框,但我想不通你为什么会这样做),如果相同,将覆盖代码上文中使用相同名称变量定义的文本框的创建。

我们接着在第一部分中以实现的内容继续书写代码。

代码展示

这里对文本框的内容的传参只是一个占位符,马上我们将会替代掉它。

实现用户交互

用户交互是一个应用的核心内容,用户交互的实现,使得用户能够控制一个应用的行为,这个应用才能与用户互动。

我们在这里要实现的主要内容主要就是 如何使 显示的单词 可被切换。现在看来,我们目前显示的单词只是文本框的固定传参,我们马上要做的,就是将显示单词的逻辑与一个变量挂钩,这样其才能被控制。

我给出的方案是这样的,将要显示的所有单词储存于列表中,然后通过 索引值 这个变量获取想要显示的单词,从而实现控制显示单词的效果。

代码展示

显然,前文所提的要与之挂钩的变量就是这个 now_word,但此时其本身又是个常数,所以我们要将其的变化与用户操作挂钩。

什么是用户操作呢?

我们来看看一些 1.0/2.0 时代常见的用户操作:

  • Button A ,Button B 被点击
  • Touch Pad 被触摸
  • 掌控板被摇晃
  • 掌控板向前倾斜

我们经常在我们的程序中使用它们做一些逻辑判断,然后控制程序做一些操作,即实现用户交互。

不过上文列举的操作都是在掌控版上的传统方法,在 3.0 上,得益于 LVGL 的加持,掌控板拥有了一种新的用户操作:按钮。

按钮

这里的使用方法所见即所得,此处不赘述,如果需要更详细的解读,请移步直播回放。

需要特别强调的是,此处用于定义按钮的变量的名称不能相同(除非你就是为了覆盖某个已创建的按钮,但我想不通你为什么会这样做),如果相同,将覆盖代码上文中使用相同名称变量定义的按钮的创建。

(与文本框的创建类似)

下面我们在掌控版上使用按钮:

代码展示

我们创建了按钮并实现了按钮的点击回调事件。

关于此处对按钮点击回调事件的详细解读,请移步直播回放。如果未来有时间,我将修改此处文本便于大家理解。

这里有一个疑点,掌控板的屏幕不是触摸屏,且也没有类似于鼠标键盘之类的外接设备,如何操作按钮呢?

产品方开发团队使用了一套不错的逻辑。分析 lv_gui.py 源码可得,他们将 ButtonA 和 ButtonB 分别绑定了 lvgl.KEY.ENTERlvgl.KEY.NEXT,这样实现了一套简易的空间交互逻辑,即 A 键确定、B 键切换焦点。我用八个字来做总结这套方案:软硬结合,新旧相接。

还记得我之前一直在强调要注意创建文本框和按钮时,定义变量的名称不能次次都相同吗?我们可以简要看一下原理:

事实上,这个变量不是一个真实的变量。产品方开发团队通过 blockly 层面的“变量”确保按钮标识符(即 btn_init 的参数 key)的唯一性/合法性。这是一个巧妙的思路。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(method) def btn_init(
self: Self@GUI_Widget,
txt: str = 'btn 1',
x: int = 10,
y: int = 10,
width: int = 60,
height: int = 34,
color: int = 16711680,
bg_color: int = 16776960,
cb: Unknown | None = None,
font: int = 16,
key: str = 'btn',
args: Unknown | None = None
) -> None

说在最后

写到这里,案例一才算是结束了,我的确没想到整理文字比直播讲出来时间还要长,感觉还要累。现在是端午假期最后一天的 20:30,留给我的时间也不多了,今天就先到这里罢。

鉴于此,我准备将我直播所讲内容的文本一分为二来写,即两个案例分开叙述。本次你看到的就是我针对直播所讲案例一内容的一个整理,希望对你有用。

  • 标题: 【88掌控日】体验魔法画布——LVGL 实战开发与技巧(上)
  • 作者: W-Can1425
  • 创建于 : 2025-06-02 17:34:10
  • 更新于 : 2025-06-02 20:33:49
  • 链接: https://can1425.flowecho.org/2025/06/02/20250602/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论