lv_obj和 lv_screen 是构建用户界面的核心基础对象

第一问

在 LVGL 8.2 中,lv_objlv_screen 是构建用户界面的核心基础对象,以下是它们的详细说明:


1. lv_obj(基础对象)

  • 定义:所有部件的基类,所有可见控件(如按钮、标签等)均继承自 lv_obj
  • 作用
    • 容器功能:可作为容器嵌套其他部件(如按钮、标签),管理子对象的布局和样式。
    • 基础属性:支持位置、大小、透明度、事件回调、样式(颜色、字体、边框等)等通用属性。
    • 自定义控件:直接使用 lv_obj 可创建简单的自定义容器(如背景面板)。
  • 示例代码
    lv_obj_t *parent = lv_obj_create(lv_scr_act());  // 创建父容器(基于当前屏幕)
    lv_obj_set_size(parent, 200, 150);                // 设置大小
    lv_obj_set_style_bg_color(parent, lv_palette_main(LV_PALETTE_BLUE), 0);  // 设置背景颜色
    

2. lv_screen(屏幕对象)

  • 定义:根对象,代表一个完整界面(如手机屏幕或窗口),是其他部件的顶层父容器。
  • 特性
    • 唯一性:每个 lv_screen 对象独立存在,无父对象(通过 lv_scr_act() 获取当前活跃屏幕)。
    • 多屏管理:可创建多个屏幕(如主界面、设置页),通过 lv_scr_load(screen) 切换显示。
    • 默认行为:首次启动时,LVGL 自动创建默认屏幕(lv_scr_act() 初始指向它)。
  • 示例代码
    lv_obj_t *screen1 = lv_scr_act();                     // 获取当前默认屏幕
    lv_obj_t *screen2 = lv_obj_create(NULL);              // 创建新屏幕(无父对象)
    lv_scr_load(screen2);                                 // 切换到 screen2
    lv_obj_t *label = lv_label_create(screen2);           // 在 screen2 上添加标签
    lv_label_set_text(label, "Hello Screen 2!");
    

关键区别

特性lv_objlv_screen
层级所有部件的父类根对象(无父对象)
用途通用容器或自定义控件的基础管理完整界面(如多屏切换)
创建方式lv_obj_create(parent)lv_obj_create(NULL) 或默认屏幕

实际应用场景

  1. lv_obj:用于布局分组(如将按钮和标签打包到同一容器)、创建背景面板、实现自定义控件。
  2. lv_screen:实现多界面切换(如主菜单→设置页→弹窗),每个屏幕独立管理子对象。

通过结合二者,可以高效构建复杂的交互界面。



第二问


多屏管理:可创建多个屏幕(如主界面、设置页),通过 lv_scr_load(screen) 切换显示。举例如下:

以下是一个通过按钮切换屏幕的完整示例代码:

#include "lvgl.h"

// 创建两个屏幕对象
lv_obj_t *screen1;
lv_obj_t *screen2;

// 点击按钮切换到 screen2 的回调函数
static void switch_to_screen2(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
        lv_scr_load(screen2); // 加载 screen2
    }
}

// 点击按钮切换回 screen1 的回调函数
static void switch_to_screen1(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
        lv_scr_load(screen1); // 加载 screen1
    }
}

void main() {
    // 初始化 LVGL...

    // 创建第一个屏幕(默认屏幕)
    screen1 = lv_scr_act();

    // 在 screen1 上添加按钮
    lv_obj_t *btn1 = lv_btn_create(screen1);
    lv_obj_set_pos(btn1, 50, 50);       // 设置按钮位置
    lv_obj_set_size(btn1, 120, 50);     // 设置按钮大小

    // 给按钮添加标签
    lv_obj_t *label1 = lv_label_create(btn1);
    lv_label_set_text(label1, "Go to Screen2");

    // 绑定按钮点击事件
    lv_obj_add_event_cb(btn1, switch_to_screen2, LV_EVENT_ALL, NULL);

    // 创建第二个屏幕
    screen2 = lv_obj_create(NULL);      // 创建新屏幕(无父对象)
    lv_obj_set_style_bg_color(screen2, lv_palette_main(LV_PALETTE_RED), 0); // 设置背景色

    // 在 screen2 上添加返回按钮
    lv_obj_t *btn2 = lv_btn_create(screen2);
    lv_obj_set_pos(btn2, 50, 50);
    lv_obj_set_size(btn2, 120, 50);

    lv_obj_t *label2 = lv_label_create(btn2);
    lv_label_set_text(label2, "Back to Screen1");
    lv_obj_add_event_cb(btn2, switch_to_screen1, LV_EVENT_ALL, NULL);
}

代码说明

  1. 多屏初始化

    • screen1:通过 lv_scr_act() 获取默认屏幕。
    • screen2:通过 lv_obj_create(NULL) 创建独立的新屏幕。
  2. 屏幕切换逻辑

    • 点击 btn1 时,触发 switch_to_screen2 回调,调用 lv_scr_load(screen2) 切换到第二个屏幕。
    • 点击 btn2 时,触发 switch_to_screen1 回调,调用 lv_scr_load(screen1) 返回第一个屏幕。
  3. 视觉效果

    • 通过 lv_obj_set_style_bg_colorscreen2 设置红色背景(默认屏幕为黑色)。

运行效果

  1. 初始显示 screen1,有一个蓝色按钮(标签为 “Go to Screen2”)。
  2. 点击按钮后,切换到红色背景的 screen2,显示返回按钮。
  3. 点击返回按钮后,回到初始的 screen1

关键 API

函数作用
lv_scr_act()获取当前活跃屏幕
lv_obj_create(NULL)创建一个无父对象的新屏幕
lv_scr_load(screen)切换到指定屏幕

实际开发中可根据需求调整屏幕布局和样式(如颜色、动画等)。







第三问

screen2 = lv_obj_create(NULL); //这个没有父对象,不会报错吗?解释如下

在 LVGL 中,screen2 = lv_obj_create(NULL); 不会报错,这是 LVGL 设计中的合法操作,原因如下:


1. 设计逻辑

  • 根对象特性:当 lv_obj_create() 的父对象参数为 NULL 时,LVGL 会将其视为新的屏幕对象(即根容器),而非普通子部件。
  • 多屏机制:LVGL 允许同时存在多个屏幕(如主界面、设置页),每个屏幕都是独立的树状结构根节点,彼此无父子关系。

2. 对比普通对象

操作结果
lv_obj_create(NULL)创建新屏幕(根对象)
lv_obj_create(parent)创建普通子对象(需有效父对象)

3. 底层实现

  • LVGL 内部会为 NULL 父对象的创建请求分配特殊标识,将其加入屏幕列表而非普通对象树。
  • 切换屏幕时(lv_scr_load()),LVGL 会自动管理屏幕的显示/隐藏状态。

4. 示例验证

// 合法操作:创建两个屏幕
lv_obj_t *screen1 = lv_scr_act();  // 获取默认屏幕
lv_obj_t *screen2 = lv_obj_create(NULL);  // 显式创建新屏幕(无父对象)

// 非法操作:普通对象必须指定父对象
lv_obj_t *child = lv_obj_create(NULL);  // 错误!此对象既非屏幕也无所属父容器
lv_obj_t *valid_child = lv_obj_create(screen1);  // 正确

5. 实际应用场景

  • 多界面切换:如主界面、设置页、弹窗等独立屏幕。
  • 动态屏幕管理:运行时按需创建/销毁屏幕(节省内存)。

总结

  • lv_obj_create(NULL) 是 LVGL 创建新屏幕的标准方式,不会报错。
  • ❌ 普通部件(非屏幕)必须指定有效的父对象,否则会导致未定义行为。

这种设计使 LVGL 的屏幕管理既灵活又高效,符合嵌入式 GUI 的资源约束需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九层指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值