3. 基础对象(lv_obj):对象的创建与删除、对象的基本属性(大小、位置、对齐)、父子对象关系与层级管理
好,咱们今天来聊聊 LVGL 里最核心的东西——lv_obj。说白了,它就是所有控件的“祖宗”。你看到的按钮、标签、滑块,本质上都是 lv_obj 的“子类”。搞懂它,后面的路就好走了。
3.1 对象的创建与删除
创建一个对象,其实就一行代码:
lv_obj_t * obj = lv_obj_create(parent);
这个 parent 就是父对象。没有父对象?那就传 NULL,它会跑到屏幕的最顶层。但我个人习惯,永远不要传 NULL。为什么?你想想看,一个没有爹的孩子,在 UI 树里就是个“孤儿”,管理起来特别麻烦。
删除对象更简单:
lv_obj_del(obj);
它会把这个对象以及它所有的子对象一起删掉。嗯,这里要注意:千万别在回调函数里乱删对象。我曾经在按钮点击事件里直接删掉了按钮本身,结果程序直接崩了。正确的做法是用 lv_obj_del_async(),它会等当前事件处理完再删。
lv_obj_del() 之后,那个指针就失效了,别再用了。
3.2 对象的基本属性:大小、位置、对齐
一个对象,最基础的三件事:多大、在哪、怎么对齐。
3.2.1 大小
lv_obj_set_width(obj, 100);
lv_obj_set_height(obj, 50);
// 或者一步到位
lv_obj_set_size(obj, 100, 50);
大小单位是像素。但 LVGL 支持自适应大小:
lv_obj_set_width(obj, LV_SIZE_CONTENT); // 根据内容自动调整宽度
这个 LV_SIZE_CONTENT 我特别喜欢用。比如做一个标签,你不想手动算宽度,直接让它自适应,省心多了。
3.2.2 位置
lv_obj_set_pos(obj, 10, 20); // 相对于父对象的坐标
坐标原点在父对象的左上角。x 向右为正,y 向下为正。嗯,这跟屏幕坐标系一致,不难理解。
3.2.3 对齐
对齐是 LVGL 的一大亮点。它让你不用手动算坐标:
lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); // 相对于父对象居中
lv_obj_align_to(obj, ref_obj, LV_ALIGN_OUT_RIGHT_TOP, 10, 0); // 相对于另一个对象
第一个参数是对象,第二个是对齐方式,第三、四是偏移量。常用的对齐方式有:
| 宏定义 | 含义 |
|---|---|
LV_ALIGN_CENTER |
居中 |
LV_ALIGN_TOP_LEFT |
左上角 |
LV_ALIGN_OUT_RIGHT_MID |
右侧外部,垂直居中 |
LV_ALIGN_OUT_BOTTOM_LEFT |
下方外部,左对齐 |
我个人习惯,能用对齐就别用手动坐标。为什么?因为一旦父对象大小变了,手动坐标就全乱了。对齐会自动重新计算,省心。
3.3 父子对象关系与层级管理
父子关系,说白了就是“谁是谁的爹”。子对象的位置、可见性、删除,都受父对象影响。
3.3.1 父子关系
创建时指定父对象:
lv_obj_t * parent = lv_obj_create(lv_scr_act()); // 创建一个父对象
lv_obj_t * child = lv_obj_create(parent); // 子对象
子对象永远在父对象之上。你移动父对象,子对象跟着跑。你隐藏父对象,子对象也看不见。你删除父对象,子对象全没了。
3.3.2 层级管理
同一父对象下的子对象,谁在上谁在下?这由创建顺序决定:后创建的在上。但你可以手动调整:
lv_obj_move_foreground(obj); // 移到最前
lv_obj_move_background(obj); // 移到最后
lv_obj_move_to_index(obj, 5); // 移到指定索引
索引从 0 开始,0 是最底层。我遇到过一个问题:两个按钮重叠了,后创建的那个挡住了前面的。用 lv_obj_move_foreground() 把想要的按钮提到最前,问题就解决了。
3.4 实战经验总结
好,说了这么多,我总结几条实战经验:
- 创建对象时,一定要指定父对象。 别偷懒传 NULL,除非你真的知道自己在干什么。
- 能用对齐就别用手动坐标。 对齐是响应式布局的基础,手动坐标是硬编码的噩梦。
- 删除对象后,指针就失效了。 记得置 NULL,或者用
lv_obj_del_async()安全删除。 - 层级管理要趁早。 等控件多了再调层级,你会想哭的。
嗯,基础对象这块就这些。说白了,它就是 LVGL 世界的“原子”。你后面学到的所有控件,都是在这个基础上加了一层皮。搞懂它,你就掌握了 LVGL 的半壁江山。