【LVGL】部件 - 基础对象
1. 引言
仅作笔记分享。
2. LVGL 编程思想
LVGL 采用的是面向对象的编程思想,以抽象的类来实例化不同的对象(部件)
2.1 举例

2.2 实现流程
C 语言中没有“类”的概念,LVGL 以结构体的形式来实现“类”的思想。
过程:
- 使用
lv_obj_t结构体实例化一个具体的对象:lv_obj(基础对象),默认就是以当前活动的屏幕作为基础对象。- 这个基础对象作为父对象衍生出更多的子对象:
lv_switch、lv_lable、lv_slider...这些部件。- 父对象衍生出这些子对象后,子对象就会继承很多父对象的属性以及行为,后面就可以用一套同意的 api 函数对这些属性和行为进行管理。

void my_gui(void)
{
lv_obj_t* switch1 = lv_switch_create(lv_scr_act()); // 创建一个在当前活动屏幕作为父对象的子对象开关switch1
lv_obj_set_size(switch_obj, 120, 60); // 设置开关部件大小
lv_obj_t* switch2 = lv_switch_create(switch1); // 可以选择活动屏幕或者前面的switch1来继承,若选择了switch2则与switch2只有命令关系,与活动屏幕才是父子关系
}
现象:

2.3 父子对象规律
- 用一个父对象创建出一个子对象时,父对象就是子对象的容器,子对象装在父对象中。
- 用一个父对象创建出一个子对象时,子对象默认创建在父对象的左上角。
3. 基础对象简介
基础对象(lv_obj)可以作为父对象,来创建其他对象,同时也可以作为部件使用。

3.1 举例
void my_gui(void)
{
lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj1, 300, 400);
}
现象:

4. 父对象和子对象的关系

4.1 举例
void my_gui(void)
{
lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj1, 300, 300);
lv_obj_set_pos(obj1, 20, 20);
lv_obj_t *obj2 = lv_obj_create(obj1);
lv_obj_set_pos(obj2, 150, 150);
}
现象:
注意,不显示的区域可以拖动控件画面来看。

5. 部件的基本属性

5.1 大小

5.1.1 部件大小(size)相关 API 函数
设置宽度:lv_obj_set_width(obj, new_width);
设置高度:lv_obj_set_height(obj, new_height);
同时设置宽度、高度:lv_obj_set_size(obj, new_width, new_height);
5.1.2 举例
void my_gui(void)
{
lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
lv_obj_set_width(obj1, 200);
lv_obj_set_height(obj1, 400);
}
现象:

5.2 位置


5.2.1 部件位置(pos)相关 API 函数
设置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);
5.2.2 举例
void my_gui(void)
{
lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
lv_obj_set_width(obj1, 200);
lv_obj_set_height(obj1, 400);
}
现象:

5.3 对齐

5.3.1 对齐相关 API 函数
方式一:
参照父对象对齐:lv_obj_set_align(obj, LV_ALIGN_...);
参照父对象对齐,再进行偏移:lv_obj_align(obj, LV_ALIGN_..., x, y);
方式二:
参照其他对象对齐(无父子关系),再进行偏移:
lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y);
基准对象 需要对齐的对象 对齐模式
5.3.2 对齐模式
有些对齐模式在某些对齐方式下是不支持的,例如参照父对象对齐的时候,不能在外部对齐。

5.3.3 举例
5.3.3.1 方式一
void my_gui(void)
{
lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
lv_obj_set_align(obj1, LV_ALIGN_CENTER);
lv_obj_align(obj1, LV_ALIGN_BOTTOM_MID, 50, 50);
}
// 这里采用向底部对齐的方式,假如再采用偏移的话,其实是会超出父对象的显示范围
现象:

5.3.3.2 方式二
void my_gui(void)
{
lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj1, 300, 300);
lv_obj_t* obj2 = lv_obj_create(lv_scr_act());
lv_obj_align_to(obj2, obj1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
}
// 以方式二来对齐,则可以选择全部的对齐模式,但是还是需要考虑到父对象的显示范围
现象:

5.4 样式

5.4.1 添加样式
5.4.1.1 普通样式
5.4.1.1.1 举例
添加普通样式:
// 定义的变量只能是全局的、静态的或动态分配的,不能是局部的,否则样式容易失效
static lv_style_t style; /* 定义样式变量 /
lv_style_init(&style); / 初始化样式 /
lv_style_set_bg_color(&style, lv_color_hex(0xf4b183)); / 设置背景颜色 /
lv_obj_t * obj = lv_obj_create(lv_scr_act()); / 创建一个部件 /
lv_obj_add_style(obj, & style, LV_STATE_DEFAULT); / 设置部件的样式 */
部件 样式 样式选择器
// 优点:共享
现象:

5.4.1.2 本地样式
5.4.1.2.1 举例
添加本地样式:
lv_obj_t * obj = lv_obj_create(lv_scr_act()); /* 创建一个部件 /
lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183),LV_STATE_DEFAULT);/ 设置部件的样式 */
部件 样式 样式选择器
// 优点:简单
// 缺点:只能应用到某一个部件上,无法全局共享
现象:

5.4.2 样式生效状态

5.4.2.1 举例
void my_gui(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act()); /* 创建一个部件 /
lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183), LV_STATE_HOVERED);/ 设置鼠标悬停状态触发样式 */
// 注意,这里设置的是鼠标悬停状态触发样式,在 PC 上生效,但是实际在触摸屏上还是不行的,注意这一点,这里只是方便演示
}
5.4.3 样式属性

5.4.3.1 查找相应样式 api 函数
写出一个普通或本地样式的 api 函数,然后查找定义即可跳转至 api 函数文件。
5.4.3.2 api 函数说明
可以在官网上寻找开发手册,查找某一个 api 函数的使用方法和功能。以下是官方开发手册:
5.4.3.3 举例
void my_gui(void)
{
lv_obj_t * obj1 = lv_obj_create(lv_scr_act()); /* 创建一个部件 /
lv_obj_set_align(obj1, LV_ALIGN_CENTER); / 设置部件对齐模式 */
lv_obj_set_style_border_color(obj1, lv_color_hex(0x56c621), LV_STATE_DEFAULT); /* 设置部件边框颜色 /
lv_obj_set_style_border_width(obj1, 10, LV_STATE_DEFAULT); / 设置部件边框宽度 /
lv_obj_set_style_border_opa(obj1, 50, LV_STATE_DEFAULT); / 设置部件边框透明度(越小越透明) */
lv_obj_set_style_outline_color(obj1, lv_color_hex(0x9aca21), LV_STATE_DEFAULT); /* 设置部件轮廓颜色 /
lv_obj_set_style_outline_width(obj1, 10, LV_STATE_DEFAULT); / 设置部件轮廓宽度 /
lv_obj_set_style_outline_opa(obj1, 200, LV_STATE_DEFAULT); / 设置部件轮廓透明度(越小越透明) */
// 设置边框和轮廓的方法非常相近,只不过api函数所在的位置不一样而已
}
现象:

5.4.4 单独设置部件中某个部分的样式

5.4.4.1 如何查看某个部件由什么部分组成
参见:
5.4.4.2 举例
void my_gui(void)
{
lv_obj_t * slider = lv_slider_create(lv_scr_act()); /* 创建一个滑块 /
lv_obj_set_align(slider, LV_ALIGN_CENTER); / 将滑块居中 */
lv_obj_set_style_bg_color(slider, lv_color_hex(0x49bc40), LV_STATE_DEFAULT | LV_PART_INDICATOR); /* 设置指示器样式颜色 /
lv_obj_set_style_bg_color(slider, lv_color_hex(0x49bc40), LV_STATE_DEFAULT | LV_PART_KNOB); / 设置手柄样式颜色 */
// 设置一个部件不同部分,要分两行代码单独设置
}
现象:

5.5 事件

5.5.1 事件相关 api 函数
添加事件:lv_obj_add_event_cb(obj, event_cb, event_code, user_data);
事件回调函数 事件类型 用户数据
删除事件:lv_obj_remove_event_cb(obj, event_cb);
5.5.2 事件类型
参见:

5.5.3 举例
include "lvgl.h"
include "stdio.h"
include "my_gui.h"
static void my_event_cb(lv_event_t * e)
{
printf("LV_EVENT_CLICKED \r\n");
}
void my_gui(void)
{
lv_obj_t * obj1 = lv_obj_create(lv_scr_act()); /* 创建一个部件 /
lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_CLICKED, NULL); / 对象按下后触发事件 */
}
现象:

5.5.4 不同事件类型共用一个事件回调函数

程序:
#include "lvgl.h"
#include "stdio.h"
#include "my_gui.h"
static void my_event_cb(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
printf(" 事件类型:按下后释放 \r\n");
} else if (code == LV_EVENT_LONG_PRESSED) {
printf(" 事件类型:按下(长按) \r\n");
}
}
void my_gui(void)
{
lv_obj_t * obj1 = lv_obj_create(lv_scr_act()); /* 创建一个部件 */
lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_CLICKED, NULL); /* 对象按下后触发事件 */
lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_LONG_PRESSED, NULL); /* 对象长按触发事件 */
}
现象:

5.5.5 不同部件共用一个事件回调函数

程序:
#include "lvgl.h"
#include "stdio.h"
#include "my_gui.h"
lv_obj_t *obj1, *obj2;
static void my_event_cb(lv_event_t * e)
{
lv_obj_t *target = lv_event_get_target(e);
if (target == obj1) {
printf(" obj1按下释放触发事件 \r\n");
} else if (target == obj2) {
printf(" obj2长按触发事件 \r\n");
}
}
void my_gui(void)
{
obj1 = lv_obj_create(lv_scr_act()); /* 创建一个部件 */
lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_CLICKED, NULL); /* 对象按下后触发事件 */
lv_obj_set_size(obj1, 200, 200);
obj2 = lv_obj_create(lv_scr_act()); /* 创建一个部件 */
lv_obj_add_event_cb(obj2, my_event_cb, LV_EVENT_LONG_PRESSED, NULL); /* 对象按下后触发事件 */
lv_obj_set_size(obj2, 100, 100);
}
现象:

博客导航
本文来自博客园,作者:膝盖中箭卫兵,转载请注明原文链接:https://www.cnblogs.com/hai-feng-dev/p/19197094

浙公网安备 33010602011771号
https://orcid.org/0000-0001-5102-772X