LVGL基础对象如何实现功能?

摘要:引言 仅作笔记分享。 LVGL 编程思想 LVGL 采用的是面向对象的编程思想,以抽象的类来实例化不同的对象(部件) 举例 实现流程 C 语言中没有“类”的概念,LVGL 以结构体的形式来实现“类”的思想。 过程: 使用lv_obj_t结构
引言 仅作笔记分享。 LVGL 编程思想 LVGL 采用的是面向对象的编程思想,以抽象的类来实例化不同的对象(部件) 举例 实现流程 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只有命令关系,与活动屏幕才是父子关系 } 现象: 父子对象规律 用一个父对象创建出一个子对象时,父对象就是子对象的容器,子对象装在父对象中。 用一个父对象创建出一个子对象时,子对象默认创建在父对象的左上角。 基础对象简介 基础对象(lv_obj)可以作为父对象,来创建其他对象,同时也可以作为部件使用。 举例 void my_gui(void) { lv_obj_t* obj1 = lv_obj_create(lv_scr_act()); lv_obj_set_size(obj1, 300, 400); } 现象: 父对象和子对象的关系 举例 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); } 现象: 注意,不显示的区域可以拖动控件画面来看。 部件的基本属性 一、大小 部件大小(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); 举例 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); } 现象: 二、位置 部件位置(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); 举例 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); } 现象: 三、对齐 对齐相关 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); 基准对象 需要对齐的对象 对齐模式 对齐模式 有些对齐模式在某些对齐方式下是不支持的,例如参照父对象对齐的时候,不能在外部对齐。 举例 方式一 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); } // 这里采用向底部对齐的方式,假如再采用偏移的话,其实是会超出父对象的显示范围 现象: 方式二 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); } // 以方式二来对齐,则可以选择全部的对齐模式,但是还是需要考虑到父对象的显示范围 现象: 四、样式 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); /* 设置部件的样式 */ 部件 样式 样式选择器 // 优点:共享 现象: 本地样式 举例 添加本地样式: lv_obj_t * obj = lv_obj_create(lv_scr_act()); /* 创建一个部件 */ lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183),LV_STATE_DEFAULT);/* 设置部件的样式 */ 部件 样式 样式选择器 // 优点:简单 // 缺点:只能应用到某一个部件上,无法全局共享 现象: 2. 样式生效状态 举例 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 上生效,但是实际在触摸屏上还是不行的,注意这一点,这里只是方便演示 } 3. 样式属性 查找相应样式 api 函数 写出一个普通或本地样式的 api 函数,然后查找定义即可跳转至 api 函数文件。 api 函数说明 可以在官网上寻找开发手册,查找某一个 api 函数的使用方法和功能。以下是官方开发手册: LVGL 官方开发手册 举例 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函数所在的位置不一样而已 } 现象: 4. 单独设置部件中某个部分的样式 如何查看某个部件由什么部分组成 参见: LVGL 官方开发手册 举例 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); /* 设置手柄样式颜色 */ // 设置一个部件不同部分,要分两行代码单独设置 } 现象: 五、事件 事件相关 api 函数 添加事件:lv_obj_add_event_cb(obj, event_cb, event_code, user_data); 事件回调函数 事件类型 用户数据 删除事件:lv_obj_remove_event_cb(obj, event_cb); 事件类型 参见: LVGL 官方开发手册 举例 #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); /* 对象按下后触发事件 */ } 现象: 1. 不同事件类型共用一个事件回调函数 程序: 点击查看代码 #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); /* 对象长按触发事件 */ } 现象: 2. 不同部件共用一个事件回调函数 程序: 点击查看代码 #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); } 现象: 博客导航 博客导航