当前位置: 首页 > news >正文

01_LVGL 对象与盒子模型详解

1. LVGL 的对象

​ 在LVGL中,⽤⼾界⾯的 基本组成部分 是对象(控件),也称为 Widgets。例如,⼀个 按钮、标签、图像、列表、图表 或者 ⽂本区域。所有的对象都使⽤ lv_obj_t 指针作为句柄进⾏引⽤。之后可以使⽤该指针来设置或获取对象的属性。

1.1对象的属性

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

  • 坐标
  • ⽗对象
  • 基于⽗对象的后代
  • 包含样式
  • 诸如 Clickable*、*Scrollable 等属性。

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

1.2 图层

​ LVGL具有图层概念,从顶层到底层依次是sys_layer层、top_layer层、act_scr层,LVGL的三层屏幕显示优先级:

屏幕活动层(active screen) < 顶层(top layer) < 系统层(system layer)

image-20250311214344794

top_layer层及sys_layer层用来创建一些随处可见的内容。

top_layer层可以用来创建菜单栏,弹出窗口等…

鼠标光标可以放在所有层的上面以确保它始终可见,也就是放在sys_layer层。

一般都是在act_scr层创建各种控件(widgets),也就是objects对象。

lv_screen_active(void); // 活动屏幕(screen_active)
lv_layer_top(void); // 顶层(top layer)
lv_layer_sys(void); // 系统层(system layer)
// 可以在不同层上创建对象(控件)
lv_obj_create(lv_screen_active());
lv_obj_create(lv_layer_top());
lv_obj_create(lv_layer_sys());

2. LVGL 对象的⼤⼩

2.1 设置⼤⼩ (Set Size)

  • 设置宽度:lv_obj_set_width(obj, new_width);
  • 设置⾼度:lv_obj_set_height(obj, new_height);
  • 同时设置宽度、⾼度:lv_obj_set_size(obj, new_width, new_height);

2.2 获取⼤⼩ (Get size)

  • 获取实际宽度:lv_obj_get_width(obj);
  • 获取实际⾼度:lv_obj_get_height(obj);
  • 获取实际可⽤的宽度:lv_obj_get_content_width(obj);
  • 获取实际可⽤的⾼度:lv_obj_get_content_height(obj);
  • 获取实际可⽤的宽⾼区域:lv_obj_get_content_coords(obj);

3. LVGL对象的位置

3.1 LVGL 屏幕原点

​ 我们常⻅的坐标系是“笛卡尔坐标系”,或者叫“直⻆坐标系”(坐标原点在左下⻆,⽔平向右为x轴正⽅向,竖直向上位y轴正⽅向**)。这种坐标系我们很熟悉,因为我们学习数学的时候⼀般就是使⽤这种坐标系。

​ 而LVGL屏幕的坐标系和我们熟悉的坐标系不⼀样,LVGL的坐标系是我们⼀般称之为“LCD坐标系”,他的原点位置和直⻆坐标系的不⼀样(坐标原点在左上⻆,⽔平向右为x轴正⽅向,竖直向下为y轴正⽅向)。

image-20250311212311691

屏幕区域的表⽰(假设屏幕是1024*600分辨率):

image-20250311212340016

3.2 设置位置 (Set Position)

  • 设置x轴⽅向的坐标位置:lv_obj_set_x(obj, new_x);
  • 设置y轴⽅向的坐标位置:lv_obj_set_y(obj, new_y);
  • 同时设置x、y坐标位置:lv_obj_set_pos(obj, new_x, new_y);

3.3 设置对⻬ (Alignment)

  • 参照⽗对象对⻬:lv_obj_set_align(obj, LV_ALIGN_…);
  • 参照⽗对象对⻬后再设置坐标位置:lv_obj_align(obj, LV_ALIGN_…, x_ofs, y_ofs);
  • 参 照 另 ⼀ 个 对 象 ( ⽆⽗⼦关 系 ) 对 ⻬ 后 设 置 坐 标 位 置 :lv_obj_align_to(obj_to_align, obj_referece,LV_ALIGN_…, x_ofs, y_ofs)

对⻬类型(LV_ALIGN_…):

image-20250311211913524

子类设置对齐时,无法超出父类(含 OUT 修饰的关键字效果等同于无 OUT 修饰)

3.4 获取位置 (Get Position)

  • 获取x轴坐标位置(在⽗对象之内):

    • lv_obj_get_x(obj); 提供原始的左上角坐标
    • lv_obj_get_x2(obj); 提供右边界坐标
  • 获取y轴坐标位置(在⽗对象之内):

    • lv_obj_get_y(obj);
    • lv_obj_get_y2(obj);

在 LVGL 中,每个对象都有一个由 lv_obj_t 表示的 coords 字段,由左上角(x1, y1)和右下角(x2, y2)坐标组成,用于确定对象的位置和尺寸。这种设计使得计算宽度、高度、对齐和重叠检测变得简单直观。

  • 获取x轴坐标位置(经过齐/平移的偏移量):lv_obj_get_x_aligned(obj);
  • 获取y轴坐标位置(经过齐/平移的偏移量):lv_obj_get_y_aligned(obj);

若设置坐标之后没有该对象没有被操作过,那么需要lv_obj_update_layout();来更新目标的坐标值

lv_obj_get_x
返回对象在其父对象坐标系中的左上角 x 坐标,直接取自对象内部存储的 coords.x1 值,是对象原始的 x 坐标。

lv_obj_get_x2
返回对象右边界的 x 坐标,即对象的最右侧位置,通常等于 coords.x2。这个值代表对象占用区域的右端点,用于计算宽度(宽度 = x2 - x1)。

lv_obj_get_x_aligned
返回对象经过对齐或样式调整后的“对齐” x 坐标。在 LVGL 中,对象可能会因布局、样式中设置的平移(translate)或其他对齐相关的属性而产生一个有效显示位置。该函数会计算并返回最终用于绘制和对齐的 x 坐标,而不仅仅是原始的 coords.x1。例如,如果对象在样式中设置了水平平移,其对齐坐标会反映这种偏移,使得对齐操作(如居中、右对齐)能基于调整后的位置进行计算。

4. 重点: 盒子模型

​ “盒子模型”在图形用户界面(GUI)开发中是一种将界面元素抽象为矩形区域(盒子)的设计思想。LVGL 以及许多其他 UI 框架都采用了这种模型。下面详细介绍盒子模型的核心概念.

据官方文档,盒子模型包含以下要素:

  1. 边界框(Boundary box)
    • 表示对象本身的宽度和高度,即对象在父容器坐标系中所占用的矩形区域。
    • 这个区域包含了边框(Border)和内容(Content)
  2. 边框宽度(Border width)
    • 对象外侧环绕的一圈“边框”的厚度。
    • 在 LVGL 中可以通过样式属性(如 border_width)进行设置。
    • 占用在边界框之内,也就是减去这部分后,才是对象的“可用区域”(内容区 + 内边距)。
  3. 内边距(Padding)
    • 对象与其 子元素 之间的空白区域。
    • 在 LVGL 的布局系统中,当对象内部需要留出一定空白时,就可以设置 padding_toppadding_bottompadding_leftpadding_right 等。
    • 只有当对象内部实际放置了子对象(例如一个按钮里有文字标签)时,这个内边距才会起作用,留出额外空间让子对象不紧贴边框。
  4. 外边距(Margin)
    • 对象外部的空白区域。
    • 仅被某些布局(如 Flex、Grid)考虑。也就是说,如果对象处于手动布局(绝对坐标)的状态,通常不会主动使用 margin 来计算位置;但在使用 lv_obj_set_flex_flow()lv_obj_set_grid_dsc_array() 等布局时,margin 就会生效,用于在对象之间留出空隙。
  5. 内容(Content)
    • 对象可用于绘制或放置子对象的“实际区域”。
    • 从“边界框”中减去“边框宽度”和“内边距”后,剩余的区域即为内容区。
    • 例如,如果边界框宽度为 300 px,边框厚度为 5 px,内边距为 30 px,则内容区的宽度 = 300 - 2×5 - 2×30 = 230 px。

放置子对象的“实际区域”。

  • 从“边界框”中减去“边框宽度”和“内边距”后,剩余的区域即为内容区。
  • 例如,如果边界框宽度为 300 px,边框厚度为 5 px,内边距为 30 px,则内容区的宽度 = 300 - 2×5 - 2×30 = 230 px。

The box models of LVGL: The content area is smaller than the bounding box with the padding and border width

相关文章:

  • GStreamer —— 2.15、Windows下Qt加载GStreamer库后运行 - “播放教程 1:Playbin 使用“(附:完整源码)
  • Windows批处理脚本入门教程
  • Ceph(2):Ceph简介
  • 自定义Linux网络协议的开发与测试
  • 暑期第一面oωo, TME一面面经
  • 用Python和Docker-py打造高效容器化应用管理利器
  • HTML基础知识
  • 机器视觉条形光源应用解析
  • 【设计模式】设计模式的分类与组织
  • IDEA2024又一坑:连接Docker服务连不上,提示:Cannot run program “docker“: CreateProcess error=2
  • 车载以太网测试-6【数据链路层】
  • 【从零开始学习计算机科学】操作系统(十)操作系统的引导程序 与 系统安全
  • 面试之《原型与原型链》
  • 《Java 加密工具与技术》ASN.1
  • C语言:6.22练习题数组解答
  • 安装、配置和启动 ssh 服务,实现远程连接服务器
  • 【推荐项目】Java的廊坊城市公交查询网站
  • 应急响应入门-bugku靶场
  • 作为一名程序员,学习AI的计划
  • 关于 Proxmark3 的详细介绍、使用指南及配置说明
  • 上海高院与上海妇联签协议,建立反家暴常态化联动协作机制
  • 男子入户强奸高龄独居妇女致其死亡,法院:属实,已执行死刑
  • 科技部等七部门:优先支持取得关键核心技术突破的科技型企业上市融资
  • 足球少年郎7月试锋芒,明日之星冠军杯构建顶级青少年赛事
  • 广东省原省长卢瑞华逝世,享年88岁
  • 体坛联播|C罗儿子完成国家队首秀,德约结束与穆雷合作