LVGL 控件之基础对象(lv_obj)

2024-08-30 14:12
文章标签 基础 对象 控件 lvgl lv obj

本文主要是介绍LVGL 控件之基础对象(lv_obj),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、 概述
    • 1、基本概念
    • 2、lv_obj_t
  • 二、 基础对象的 API 函数
    • 1、Coordinates(坐标)
      • 1.1 单位
      • 1.2 盒子模型
    • 2、Size(大小)
    • 3、Position(位置)
    • 4、Alignment(对齐)
    • 5、Parents and children
    • 6、Display and Screens(显示和屏幕)
    • 7、Events(事件)
    • 8、Styles(样式)
    • 9、Flags(宏开关)
    • 10、Groups(组)
    • 11、通用函数
  • 三、实例


一、 概述

1、基本概念

基础对象的作用有四个:

  1. 管理其他部件的基本属性;
  2. 作为背景装饰;
  3. 辅助布局;
  4. 界面切换。

基础对象 实现了屏幕上控件的基本属性,例如:

  • 坐标
  • 父对象
  • 基于父对象的后代
  • 包含样式
  • 诸如 ClickableScrollable 等属性。

在面向对象的思想中,基础对象就是 LVGL 中所有其他对象都继承自的基类

基础对象的功能可以与其他控件一起使用。 例如 lv_obj_set_width(slider, 100)

基础对象可以直接用作一个简单的控件:它只不过是一个矩形。 在 HTML 术语中,将其视为 <div>。

在这里插入图片描述
在设计较为复杂的 GUI 界面时,不同功能的模块之间需要清晰地划分区域,此时,我们可以使用基础对象作为背景,对不同的区域进行划分。

父对象可以被看作是其子对象的容器,每个对象只有一个父对象(screen 对象没有父对象),父对象可以有无限数量的子对象,同时父对象的类型是没有限制。父对象和子对象之间具有如下两点特性:

  1. 一起移动
    如果父对象的位置更改,则子对象将随父对象一起移动,因此子对象的坐标位置是以父对象的左上角而言的,而不是以屏幕的左上角。
  2. 子对象只能在父对象的区域内显示
    如果子对象的一部分在父对象的外面,那么子对象的这一部分将不会被显示出来。

2、lv_obj_t

lv_obj_t 定义在目录 lvgl\src\core\lv_obj.h 中:

struct _lv_obj_t {const lv_obj_class_t * class_p;  // 描述每个对象的通用方法lv_obj_t * parent;				 // 指向父对象_lv_obj_spec_attr_t * spec_attr; // 特殊的、很少使用的属性_lv_obj_style_t * styles;        // 样式的描述符(属性和值的集合)
#if LV_OBJ_STYLE_CACHEuint32_t style_main_prop_is_set;uint32_t style_other_prop_is_set;
#endifvoid * user_data;
#if LV_USE_OBJ_IDvoid * id;
#endiflv_area_t coords;							// 表示该对象屏幕的哪个区域lv_obj_flag_t flags;						// 为 uint32_t 类型,用来存放宏标志lv_state_t state;							// 为 uint16_t 类型,用来表示状态uint16_t layout_inv : 1;uint16_t readjust_scroll_after_layout : 1;uint16_t scr_layout_inv : 1;uint16_t skip_trans : 1;uint16_t style_cnt  : 6;uint16_t h_layout   : 1;uint16_t w_layout   : 1;uint16_t is_deleting : 1;
};

二、 基础对象的 API 函数

1、Coordinates(坐标)

LVGL 的坐标设置的概念受到 CSS 的启发,LVGL 并不完全实现了 CSS,但实现了一个类似的子集(有的地方进行了微小调整)。简而言之:

  • 显式设置的坐标存储在样式中(大小、位置、布局等)
  • 支持最小宽度、最大宽度、最小高度、最大高度
  • 有像素、百分比和“内容(content)”单位
  • x=0;y=0 坐标表示父对象的 左上角 + 左或上内边距 + 边框的宽度
  • 宽/高(width/height)表示完整的尺寸,“内容区域”较小,带有填充和边框宽度
  • 支持 flexboxgrid 布局的部分功能(子集)

1.1 单位

  • 像素pixel):简单地说就是一个以像素为单位的位置。整数总是指像素。
    例如 lv_obj_set_x(btn, 10)(设置按钮的横(x)坐标为 10 个像素)
  • 百分比percentage):对象或其父对象大小的百分比。 lv_pct(value) 将一个值转换为百分比。
    例如 lv_obj_set_width(btn, lv_pct(50)) (将按钮的宽度设置为父级宽度的 50%)
  • LV_SIZE_CONTENT:设置对象宽度/高度的特殊值,将会根据子对象所需的大小自动调整自身大小。类似于 CSS 中的 auto。
    例如:lv_obj_set_width(btn, LV_SIZE_CONTENT)(将按钮的宽度设置为自适应内容宽度)

1.2 盒子模型

LVGL 遵循 CSS 的 border-box 模型。一个对象的“盒子”由以下部分构成:

  • 边界框:元素的宽度/高度。
  • 边框宽度:边框的宽度。
  • 填充:对象与其子元素之间的间距。
  • 外边距:对象外部的间距(仅由某些布局考虑)
  • 内容:内容区域,即边界框减去边框宽度和内边距的大小。

注意:LVGL不会立即重新计算所有坐标变化,这样做是为了提高性能。相反,对象会被标记为"脏(dirty)",在重新绘制屏幕之前,LVGL会检查是否有任何"dirty"对象。如果有,则会刷新它们的位置、大小和布局。

换句话说,如果您需要获取对象的坐标,并且坐标刚刚发生了变化,LVGL需要强制重新计算坐标。要做到这一点,请调用 lv_obj_update_layout()

大小和位置可能取决于父级或布局。因此,lv_obj_update_layout() 会重新计算 obj 屏幕上所有对象的坐标。

2、Size(大小)

函数含义
lv_obj_set_width(obj, new_width)修改对象的宽度
lv_obj_set_height(obj, new_height)修改对象的高度
lv_obj_set_size(obj, new_width, new_height)同时修改对象的宽度和高度

3、Position(位置)

函数含义
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 轴的位置

4、Alignment(对齐)

函数含义
lv_obj_set_align(obj, LV_ALIGN_…)将对象参照其父对象对齐

调用该函数后,每个 x 和 y 设置都将适用于设置对齐模式。例如,这会将对象从其父对象的中心移动 10(x),20(y) 像素:

lv_obj_set_align(obj, LV_ALIGN_CENTER);
lv_obj_set_pos(obj, 10, 20);//Or in one function
lv_obj_align(obj, LV_ALIGN_CENTER, 10, 20);
函数含义
lv_obj_align_to(obj_to_align, obj_reference, LV_ALIGN_…, x, y)将一个对象参照另一个对象对齐

例如,让图片下方的文本参照图片对齐:

lv_obj_align_to(text, image, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

所有的对齐方式如下:
在这里插入图片描述

5、Parents and children

函数含义
lv_obj_set_parent(obj, new_parent)为对象设置新的父级
lv_obj_get_parent(obj)获取当前父级
函数含义
lv_obj_get_child(parent, idx)获取父母的特定孩子

下面是 idx 的一些示例:

  • 0 获取创建的第一个子项
  • 1 获取创建的第二个子项
  • -1 获取最后创建的子项

父级的孩子们可以这样迭代:

uint32_t i;
for(i = 0; i < lv_obj_get_child_count(parent); i++) {lv_obj_t * child = lv_obj_get_child(parent, i);/*Do something with child*/
}
函数含义
lv_obj_get_index(obj)返回对象在其父对象中的索引
lv_obj_move_foreground(obj)对象带到前台
lv_obj_move_background(obj)将对象移到后台
lv_obj_move_to_index(obj, index)更改对象在其父对象中的索引
lv_obj_swap(obj1, obj2)交换两个对象的位置
(列表框中,它可用于对列表框项目进行排序。)

6、Display and Screens(显示和屏幕)

在 LVGL 中,对象层次结构的最高级别是 display,它代表显示设备(物理显示器或模拟器)的驱动程序。 一个显示器可以有一个或多个与其相关联的屏幕。 每个屏幕都包含图形控件的对象层次结构,代表覆盖整个显示的布局。

函数含义
lv_screen_load(screen)激活屏幕对象
lv_screen_active()提供指向活动屏幕的指针
lv_display_set_default()明确指定屏幕
lv_obj_get_screen(obj)获取对象的屏幕

当你创建了一个像 lv_obj_t * screen = lv_obj_create(NULL) 这样的屏幕时,你可以用 lv_screen_load(screen) 激活它。

或者直接使用:lv_screen_load(screen)

7、Events(事件)

函数含义
lv_obj_add_event_cb(obj, event_cb, LV_EVENT_…, user_data)为对象设置事件回调
lv_event_send(obj, LV_EVENT_…, param)手动向对象发送事件

更多关于事件的讲解会在后续的内容提到。

8、Styles(样式)

函数含义
lv_obj_add_style(obj, &new_style, selector)向对象添加新样式

selector 可以组合使用。 例如 LV_PART_SCROLLBAR | LV_STATE_PRESSED

基本对象使用 LV_PART_MAIN 样式属性和带有典型背景样式属性的 LV_PART_SCROLLBAR

9、Flags(宏开关)

函数含义
lv_obj_add/remove_flag(obj, LV_OBJ_FLAG_…)为对象添加/移除宏标志
lv_obj_set_flag(obj, LV_OBJ_FLAG_…, true/false)为对象设置宏
  • LV_OBJ_FLAG_HIDDEN 隐藏对象。 (就像它根本不存在一样)
  • LV_OBJ_FLAG_CLICKABLE 使输入设备可点击对象
  • LV_OBJ_FLAG_CLICK_FOCUSABLE 单击时将焦点状态添加到对象
  • LV_OBJ_FLAG_CHECKABLE 对象被点击时切换选中状态
  • LV_OBJ_FLAG_SCROLLABLE 使对象可滚动
  • LV_OBJ_FLAG_SCROLL_ELASTIC 允许在内部滚动但速度较慢
  • LV_OBJ_FLAG_SCROLL_MOMENTUM 在“抛出”时使对象滚动得更远
  • LV_OBJ_FLAG_SCROLL_ONE 只允许滚动一个可捕捉的子项
  • LV_OBJ_FLAG_SCROLL_CHAIN_HOR 允许将水平滚动传播到父级
  • LV_OBJ_FLAG_SCROLL_CHAIN_VER 允许将垂直滚动传播到父级
  • LV_OBJ_FLAG_SCROLL_CHAIN 简单的包装 (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER)
  • LV_OBJ_FLAG_SCROLL_ON_FOCUS 自动滚动对象以使其在聚焦时可见
  • LV_OBJ_FLAG_SCROLL_WITH_ARROW 允许使用箭头键滚动聚焦对象
  • LV_OBJ_FLAG_SNAPPABLE 如果在父对象上启用了滚动捕捉,它可以捕捉到这个对象
  • LV_OBJ_FLAG_PRESS_LOCK 保持对象被按下,即使按下从对象上滑动
  • LV_OBJ_FLAG_EVENT_BUBBLE 也将事件传播给父级
  • LV_OBJ_FLAG_GESTURE_BUBBLE 将手势传播给父级
  • LV_OBJ_FLAG_ADV_HITTEST 允许执行更准确的命中(点击)测试。例如考虑圆角。
  • LV_OBJ_FLAG_IGNORE_LAYOUT 使对象可以通过布局定位
  • LV_OBJ_FLAG_FLOATING 当父级滚动时不要滚动对象并忽略布局
  • LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS 启用 LV_EVENT_DRAW_TASK_ADDED 发送事件
  • LV_OBJ_FLAG_OVERFLOW_VISIBLE 不要将子项的内容剪裁到父项的边界
  • LV_OBJ_FLAG_FLEX_IN_NEW_TRACK 在此项目上启动新的弹性轨道
  • LV_OBJ_FLAG_LAYOUT_1 自定义标志,可供布局免费使用
  • LV_OBJ_FLAG_LAYOUT_2 自定义标志,可供布局免费使用
  • LV_OBJ_FLAG_WIDGET_1 自定义标志,组件免费使用
  • LV_OBJ_FLAG_WIDGET_2 自定义标志,组件免费使用
  • LV_OBJ_FLAG_USER_1 自定义标志,用户免费使用
  • LV_OBJ_FLAG_USER_2 自定义标志,用户免费使用
  • LV_OBJ_FLAG_USER_3 自定义标志,用户免费使用
  • LV_OBJ_FLAG_USER_4 自定义标志,用户免费使用

使用实例:

/*Hide on object*/
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);/*Make an object non-clickable*/
lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE);

10、Groups(组)

函数含义
lv_group_add_obj(group, obj)将对象添加到组
lv_obj_get_group(obj)查看对象属于哪个组
lv_obj_is_focused(obj)返回对象当前是否聚焦在其组上。 如果对象未添加到组中,则将返回 false

11、通用函数

函数描述
lv_obj_create ()创建基础对象(矩形)
lv_obj_set_user_data()设置对象的 user_data 字段
lv_obj_has_flag()检查是否在对象上设置了指定的标志
lv_obj_has_flag_any()检查是否在对象上设置了任何标志
lv_obj_get_state()获取对象的状态
lv_obj_has_state()检查对象是否处于指定状态
lv_obj_get_group()获取对象的组
lv_obj_get_user_data()获取对象的用户数据
lv_obj_allocate_spec_attr()为对象分配特殊数据(还未分配时)
lv_obj_check_type()检查 obj 的类型
lv_obj_has_class()检查是否有任何对象具有指定的类
lv_obj_get_class()获取对象的类
lv_obj_is_valid()检查是否有任何对象在活动

三、实例

这里定义了一个按钮,并简单添加了一些样式,并为它添加了一个点击事件。点击按钮后,其颜色会变成灰色。

static lv_style_t style_btn; // 样式对象
static lv_obj_t *btn;static void obj_event_cb(lv_event_t *e)
{lv_style_set_bg_color(&style_btn, lv_palette_main(LV_PALETTE_GREY)); // 将按钮背景颜色变成灰色lv_obj_add_style(btn, &style_btn, LV_STATE_DEFAULT);                 // 将样式对象添加到button
}void my_gui(void)
{btn = lv_btn_create(lv_scr_act());  // 创建一个button对象lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0);     // 居中lv_obj_set_height(btn, 30);                   // 设置button高度lv_obj_t *label;label = lv_label_create(btn);                 // 为button添加一个label子对象lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);   // 居中lv_label_set_text(label, "Hello World");      // 设置label文字lv_style_init(&style_btn);                                 // 初始化lv_style_set_radius(&style_btn, 10);                       // 设置圆角lv_style_set_border_color(&style_btn, lv_color_white());   // 设置边框颜色lv_style_set_border_opa(&style_btn, LV_OPA_30);            // 设置样式边框过滤颜色lv_obj_add_style(btn, &style_btn, LV_STATE_DEFAULT);       // 将样式对象添加到buttonlv_obj_add_event_cb(btn, obj_event_cb, LV_EVENT_PRESSED, NULL); // 添加点击事件
}

在模拟器上运行为:

点击按钮后:

在这里插入图片描述

这篇关于LVGL 控件之基础对象(lv_obj)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1121044

相关文章

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

c++基础版

c++基础版 Windows环境搭建第一个C++程序c++程序运行原理注释常亮字面常亮符号常亮 变量数据类型整型实型常量类型确定char类型字符串布尔类型 控制台输入随机数产生枚举定义数组数组便利 指针基础野指针空指针指针运算动态内存分配 结构体结构体默认值结构体数组结构体指针结构体指针数组函数无返回值函数和void类型地址传递函数传递数组 引用函数引用传参返回指针的正确写法函数返回数组

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)