LVGL的基础知识总结

news2025/4/16 18:34:24

详细的内容可以参考正点原子的LVGL开发指南,本文只记录重点内容 

正点原子后续的例程都是基于操作系统来写的

面向对象

LVGL 中,用户界面的基本构建成分是对象,也称为小部件,例如:按钮、标签、图片、列表、图表、文本区域,等等。值得注意的是,LVGL 图形库虽然是由 C 语言开发的,但其所采用的是一种面对对象编程思维,这就涉及到了“类”的概念。

C语言中,并没有“类”的概念,而 LVGL通过结构体的形式实现了“类”的功能(并非真的“类”)

也就是说,每一个部件都是一个对象,我们直接针对部件对象来操作即可。

为了方便统一管理,LVGL的所有部件都会有一个父类,LVGL中,父类是属于一种最基础的基础对象。

基础对象

基础对象本身就是一个小部件,当它被创建出来之后,其呈现出一个矩形。

除此之外,基础对象还是其他小部件的父类,所有部件的位置、大小等基本属性都是归基础对象管理的。屏幕就是最顶层的一个父类(除了屏幕没有自己的父类,其他部件都有)

由上图可知,在 LVGL 中,首先定义了 lv_obj_t 这个结构体,然后通过这个结构体去实例化一个基础对象(lv_obj),这个基础对象将作为父对象,去衍生更多的子对象(其他部件)。

值得注意的是,通过这种“类”的方式去衍生其他部件,所衍生出来的部件将会继承父对象的一些基本属性,例如大小、位置、样式,等等,因此,我们可以通过一套统一的函数去管理不同部件的基本属性。

基础对象的作用有四个:

① 管理其他部件的基本属性;

② 作为背景装饰;

③ 辅助布局;

④ 界面切换。

第一个作用内容比较多,我们后面单独讨论,先说下其他三个作用

1. 作为背景装饰

当基础对象被创建出来后,它默认是一个圆角矩形,如下图所示:

在设计较为复杂的 GUI 界面时,不同功能的模块之间需要清晰地划分区域,此时,我们

可以使用基础对象作为背景,对不同的区域进行划分。

2. 辅助布局

GUI 界面中有一些组成内容相似的模块时,可以利用基础对象作为父对象,创建出其他的部件,这些部件将出现在基础对象内部,此时,我们只需要管理各基础对象之间的布局即可,其他的部件会随之变化。类似于编组。

3. 界面切换

当基础对象做为父对象,创建出其他的部件时,这些被创建出来的部件将出现在其父对象的内部,换言之,此时的基础对象就是一个容器,它里面子对象会随之移动。在 UI 设计中,我们可以利用上述的特性,实现界面的切换,示意图如下所示:

由上图可知,基础对象 12 分别用于管理界面 12,它们之中存在一些子对象(例如开关),当用户需要切换界面时,只需切换容器即可。

LVGL 官方提供了很多与基础对象相关 API 函数,如下表所示:

最常用的有两个

创建基础对象

这里的创建函数为lv_obj_create

传入一个父对象,返回一个基础对象。

注意,LVGL里的对象类型都是lv_obj_t,但是有不同的创建函数

获取对象状态

LVGL屏幕

上面说了,屏幕是属于最顶层的一个父类,也就是一个基础对象。

示例如下:

对象的性质

除了基础对象,其他部件也属于一个一个的对象,在学习其他部件之前,我们先借着基础对象来了解下,这些部件对象都有哪些基本的性质。

对象的基本属性

LVGL 中,每个对象都有一些相同的基本属性,例如:

① 父类

②  大小

③  位置

④  样式

⑤ 事件

这些属性都是通用的,所有对象都有,所以设置函数只针对属性,而具体的对象是通过参数传递进入的。

对象的私有属性

在对象衍生的过程中,不同的对象(部件)会拥有一些特殊的属性,也称为私有属性。

注意私有属性设置函数命名和通用属性设置函数命名的区别,通用属性设置函数的第二个字母为obj,而私有属性设置函数的第二个字母就是对应的部件名

父对象与子对象的关系

父对象(下文称为父类)可以视为子对象(下文称为子类)的容器,当子类被创建出来之 后,它是在父类里面的。注意:一个父类可以拥有多个子类,而子类就只有一个父类(屏幕除外)。

接下来,我们介绍父类和子类之间的关系:

1

父类移动,则子类也会随着父类移动,如下图所示:

2

子类移动,父类并不会随之移动,如果子类移动的位置超出父类的范围,则超过的部分默认不可见,如下图所示:

上图中,子类的黄色部分超出了父类的范围,这个部分将默认不可见。

3

子类在设置坐标位置时,坐标原点在父类的左上角,示意图如下所示:

在上图的例子中,父类设置位置时,是以整个显示屏的坐标原点(0,0)为参考点的,而对于子类来说,其设置位置时,则是以父类的左上角坐标点为参考点,如上图中的点A(400,240)

创建对象与删除对象

LVGL 中,用户可以在程序运行时动态创建或者删除一个对象。当对象被创建时,将消耗一定的内存,而当其被删除时,这部分内存将得到释放。

注意,基础对象创建时中间的关键词是obj

创建对象的函数只是有统一的格式,而这些删除对象的函数是通用的。

页面切换

我们介绍界面切换的两种实现方法:

方法一:删除法

当用户删除一个父对象时,它所有的子对象也会被一并删除,因此,我们需要实现界面的切换,可以调用 lv_obj_del 函数,直接删除基础对象(父对象),然后再创建新的界面,这样即可实现界面切换,示意图如下所示:

方法二:隐蔽法

此方法的原理和删除法类似,只不过这里是将界面隐藏起来,需要的时候还能还原。

注意:

隐藏的界面并未被删除,其占用内存也没有得到释放,因此,当用户使用此方法切换界面时,需要考虑内存溢出的隐患。隐蔽法的示意图如下所示:

由上图可知,隐藏法的实现逻辑如下:先创建出不同的界面,然后调用 lv_obj_add_flag

数,为指定的界面添加隐藏的标志,此时,该界面将隐藏,而当我们需要显示某个界面时,只需要调用 lv_obj_clear_flag 函数,清除隐藏属性即可。注意:不要同时清除多个界面的隐藏属性,否则可能出现显示混乱的问题。

两种方法各有什么利弊呢?后续再补充。

LVGL 图层

关于 LVGL 的图层,大家只需要搞清楚 3 个问题即可:

① 当用户创建两个对象,而这两个对象的区域出现重叠时,重叠的部分将如何绘制?

② 两个对象出现重叠,怎样把底下的对象移到上层?

LVGL 的图层有哪些?

接下来,我们围绕着这三个问题来讲解 LVGL 图层的知识。

活动屏幕层就是我们常规使用的那一层,顶层一般是用于弹窗,系统层一般是用于鼠标显示。

LVGL 布局

LVGL 的布局设计深受 CSS 启发,其主要内容涉及 3 个方面:坐标位置、大小以及对齐方式

对齐部分表格太长,所以直接参考正点原子开发指南的这一部分即可。

对齐分为内部对齐和外部对齐,内部对齐是子类和父类之间的对齐;外部对齐是各父类整体之间的对齐。

LVGL 中,常用于设置对齐方式的函数有 3 个:

LVGL样式属性

样式即对象的外观,而 LVGL 的样式设置深受 CSS 的启发,其特点如下:

LVGL 样式设置方法

LVGL 中,设置样式属性的方法有两个:

普通样式适合批量应用,本地样式针对性强。

注意二者在设置函数命名上的差异,本地样式相对普通样式,多了个obj,说明它是针对具体对象的,而上面是普遍使用的。

部件组成部分

在lvgl中,各种部件都是由不同的部分组成的,举个例子,当我们绘制一个圆角矩阵时,可将其分解为两个部分,例如直线部分和圆弧部分,这样即可组成为圆角矩阵,如下图所示:

LVGL中,也利用了上述的原理,将一个复杂的部件分解成多个组成部分,这样我们即可单独地设置某个组成部分的样式。注意:如果用户想设置某个组成部分的样式,则需要在设置样式时选择该组成部分的对应枚举。各个组成部分对应的枚举如下表所示:

注意,这里是全部列出来了,实际上,不同的部件有着不同的组成部分。

接下来,我们结合上表,以进度条部件(Slider)为例,分析它的组成部分,如下图所示:

部件的状态

LVGL 中,所有的部件状态如下表所示:

上表中,部件状态相关的枚举较少且不难理解,我们一般在两种情况下会用到状态枚举:

上面说了样式的设置,那么,具体有哪些样式可以进行设置呢?

涉及的样式比较多,这里就不一一列出来了,可自行参考开发指南6.4.4 LVGL 样式属性

其实LVGL的绘制无非就是创建部件对象,然后设置对应的属性。

注意:16位的颜色深度不支持Alpha通道的透明属性设置。

LVGL 字库使用

LVGL 的字体功能是较为强大的:支持 UTF-8 编码、图标字体、自定义字体、最高 8bpp的抗锯齿,等等。值得注意的是,bpp 值越大,字体的边缘会越平滑,但其对内存的占用就越多,在界面上进行字体渲染时,绘制速度也会越慢,一般的项目,采用 4bpp 就足够了。

启用 UTF-8 编码

LVGL 支持 2 种编码方式:第一种是 ASCII 编码,这种编码只支持英文字符的显示;第二种是 UTF-8 编码,这种编码可以支持全球所有字符的显示。用户需要在 LVGL 工程中启用UTF-8 编码,可以打开 lv_conf.h 文件,修改 LV_TXT_ENC 配置项,如下源码所示:

默认就是UTF-8编码。

这里建议大家将 MDK 软件设置为 Chinese GB2312 编码,以更好地兼容中文。

使用 LVGL 内置图标字体

图标字体是 web 前端中流行的一种技术,它以字体的形式,呈现出一个单色的图标。在 LVGL 中,自带了许多常用图标字体,这极大地方便了用户的界面开发。大家需要使用这些图标字体,可以打开lv_symbol_def.h文件,查找相应的图标字体枚举。

当用户调用上述的图标字体枚举,它们将显示成图标。

使用 LVGL 内部字库

LVGL 提供了一套内置的字库,这些字库在移植的时候已经被添加到工程当中,我们打开

Middlewares/lvgl/src/font 分组,即可找到这些字库文件,如下图所示:

接下来,我们介绍 LVGL 内部字库的使用流程:

1. 使能字库

打开 lv_conf.h 文件,将所需要使用的内部字库使能(宏定义置 1

2.调用字库

使用自定义字库

另外,还有自定义字库的使用,具体可参考开发手册8.4 使用自定义字库

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

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

相关文章

【Python_Zebra斑马打印机编程学习笔记(三)】解决ZPL指令无法显示中文的问题

解决ZPL指令无法显示中文的问题 解决ZPL指令无法显示中文的问题前言一、问题描述二、字符集、码表文件、字库文件1、字符集2、码表文件3、字库文件 三、两种设置中文字体的方式1、通过设置字符集、码表文件、字库文件改变默认字体2、通过^CF指令设置标准字体名称改变默认字体 解…

DOM 创建节点、添加节点和删除节点

创建元素节点 document.createElement(‘标签名’) 创建文本节点document.createTextNode ( 内容 ) 根据传入的标签名创建出一个空的元素对象创建出来的默认不显示,要成为别人的子元素才能显示,所以要结合appendChild使用 添加节点(后面&am…

【AI Agent系列】【MetaGPT多智能体学习】4. 基于MetaGPT的Team组件开发你的第一个智能体团队

本系列文章跟随《MetaGPT多智能体课程》(https://github.com/datawhalechina/hugging-multi-agent),深入理解并实践多智能体系统的开发。 本文为该课程的第四章(多智能体开发)的第二篇笔记。主要是对MetaGPT中Team组件…

每日一练:LeeCode-701、二叉搜索树中的插入操作【二叉搜索树+DFS+全搜】

本文是力扣 每日一练:LeeCode-701、二叉搜索树中的插入操作【二叉搜索树DFS全搜】学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定二叉搜索树(BST)的根节点 root 和要插入树中的值 …

机器学习图像识别如何处理标签以外的图像?

机器学习图像识别技术是一种基于人工智能的图像处理方法,它通过训练大量的图像数据集来让计算机学习如何识别和分类图像。在图像识别任务中,我们通常需要对图像进行标注和分类,以便让计算机能够从中学习。但是,有时候我们可能会遇…

减少页面加载时间:提升用户体验的关键

✨✨ 祝屏幕前的您天天开心,每天都有好运相伴。我们一起加油!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 目录 引言 一、为什么页面加载时间重要? 二、如何减少页面加载时间? …

集中和离散

数据分类&#xff1a;定性(分类&#xff0c;顺序)&#xff0c;定量(数值) 分类&#xff1a;男&#xff0c;女 顺序&#xff1a;高&#xff0c;中&#xff0c;低 数值&#xff1a;可计算的数字 数据等级&#xff1a;分类<顺序<数值。高级数据可以用低级数据&#xff0c…

day09_面向对象_构造方法_封装

今日内容 零、 复习昨日 一、构造方法 二、重载 三、封装 零、 复习昨日 1 类和对象是什么关系? 类是模板(原材料)对象是具体实例(成品)类创建出对象 2 类中有什么?(类的成员) 成员属性(成员变量), 成员方法 3 创建对象的语法? 类名 对象名 new 类名(); 4 调用对象属性,方法…

音频筑基:CD还是HiRes?高清音频分类一文说透

音频筑基&#xff1a;CD还是HiRes&#xff1f;高清音频分类一文说透 前言音乐品质分类相关资料 前言 音频信号中&#xff0c;经常遇到高清音乐、无损音质、CD、HiRes等说法&#xff0c;本文主要在纯数字信号级别&#xff0c;从音源分类和编码质量两个维度&#xff0c;做一个分析…

[AutoSar]BSW_Com06 CAN报文应用层到Can总线的函数调用

目录 关键词平台说明一、背景二、PDU转换三、函数调用 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c;芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)autosar版本4.3.X >>>>>回到总目…

《商用密码应用安全性评估管理办法》解读

根据《中华人民共和国密码法》&#xff08;以下简称《密码法》&#xff09;、《商用密码管理条例》&#xff08;以下简称《条例》&#xff09;等法律法规&#xff0c;国家密码管理局研究制定了《商用密码应用安全性评估管理办法》&#xff08;国家密码管理局令第3号&#xff09…

Vue页面更新后刷新页面不会渲染解决

小编今天犯了个很低级的错误&#xff0c;导致VUE页面刷新样式不会更新的问题&#xff01; 解决方法&#xff1a;查看你的路由路径大小写是否正确&#xff01;小编是犯了这种错误&#xff0c;特此分享下&#xff01;

Vite 构建的 Vue3 项目如何整合 Monaco Editor 代码编辑器

目录 &#x1f981; 一. 前言&#x1f981; 二. 探索过程2.1 安装2.2 配置 Monaco Editor2.3 编写 Monaco Editor 代码编辑器2.3.1 创建 Coding Editor 组件2.3.2 父组件使用 CodingEditor 组件 2.4 效果展示 三. 总结 &#x1f981; 一. 前言 各位好&#xff01;我是&#x1…

Unity 预制体与变体

预制体作用&#xff1a; 更改预制体&#xff0c;则更改全部的以预制体复制出的模型。 生成预制体&#xff1a; 当你建立好了一个模型&#xff0c;从层级拖动到项目中即可生成预制体。 预制体复制模型&#xff1a; 将项目中的预制体拖动到层级中即可复制。或者选择物体复制粘贴。…

2024年2月总结及随笔之平平安安过大年

1. 回头看 日更坚持了425天。 读《千脑智能》开更并更新完成 读《十堂极简人工智能课》开更并更新完成 读《人工不智能&#xff1a;计算机如何误解世界》开更并持续更新中 2023年至2024年2月底累计码字898882字&#xff0c;累计日均码字2115字。 2024年2月码字84475字&am…

【机器学习:Recommendation System】推荐系统

推荐系统&#xff08;或推荐系统&#xff09;是一类机器学习&#xff0c;它使用数据来帮助预测、缩小范围并在呈指数级增长的选项中找到人们正在寻找的内容。 【机器学习&#xff1a;Recommendation System】推荐系统 什么是推荐系统&#xff1f;用例和应用电子商务与零售&…

基于springboot+vue的常规应急物资管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

动态规划|【路径问题】礼物的最大价值(LCR 166.珠宝的最高价值)

目录 题目 题目解析 思路 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 代码 题目 LCR 166. 珠宝的最高价值 &#xff08;现在leetcode上面是这个题&#xff09;这个题跟下面这个题叙述方式一样&#xff0c;就拿下面这个 题来讲解&#xff09; 题目描述&…

基于语义解析的KBQA——代码和论文详细分析

根据论文&#xff1a;Semantic Parsing on Freebase from Question-Answer Pairs&#xff0c;分析其代码和步骤&#xff0c;以加强对这一流程的深入理解&#xff0c;重点关注模型的输入、输出和具体方法。 前言 提供阅读本文的前提知识&#xff0c;引用自Semantic Parsing on…

Python利用pandas对数据进行特定排序

更多Python学习内容&#xff1a;ipengtao.com 在数据分析和处理过程中&#xff0c;排序是一项常见而重要的操作。Python中的pandas库提供了丰富的功能&#xff0c;可以方便地对数据进行各种排序操作。本文将详细介绍如何利用pandas对数据进行特定排序&#xff0c;包括基本排序、…