目录
LVGL是一个轻量级的嵌入式图形库。LVGL的项目作者是来自匈牙利首都布达佩斯的 Gábor Kiss-Vámosi 。Kiss 在2016年将其发布在 GitHub上。 当时叫 LittlevGL而不是LVGL,后来作者重新命名为 LVGL,甚至连仓库地址都改了。 像一般的开源项目的那样,它是作为一个人的项目开始的。 从那时起,陆续有近 100 名贡献者参与了项目开发,使得 LVGL 逐渐成为最受欢迎的嵌入式图形库之一。
LVGL是一个轻便且多功能的图形库,我们可以在官网查看她的所有特性。
Code::Block在资料中 “03_开发软件/codeblocks-20.03mingw-setup”,选中“codeblocks-20.03mingw-setup.zip”右键进行解压分卷包:
解压后,双击“codeblocks-20.03mingw-setup.exe”安装Code::Block:
成功安装了 Code::Block 之后,进入下面这个目录双击 “lvgl.cbp” 打开项目:
LVGL采用面向对象的编程思想(OOP),她的基本构造块(类)是对象(实例),也就是我们所说的部件(Widgets)就是一个个部件,比如button、label、image等等。
- lv_init
- _lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t)); // 初始化显示器链表
- lv_disp_drv_register
- _lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll)); // 注册显示器到链表
- disp->act_scr = lv_obj_create(NULL); // 在显示器上创建一个默认屏幕
- lv_obj_class_create_obj
- obj->coords.x1 = 0;
- obj->coords.y1 = 0;
- obj->coords.x2 = lv_disp_get_hor_res(NULL) - 1; // 设置屏幕的水平宽度
- obj->coords.y2 = lv_disp_get_ver_res(NULL) - 1; // 设置屏幕的垂直高度
-
-
lv_scr_act(void); // 活动屏幕 disp->act_scr
lv_layer_top (void); // 顶层 disp->top_layer
lv_layer_sys (void); // 系统层 disp->sys_layer
-
- /**
- * @file main
- *
- */
-
- /*********************
- * INCLUDES
- *********************/
- #include
- #include
-
- #include "lvgl/lvgl.h"
- #include "lv_100ask_teach_demos/lv_100ask_teach_demos.h"
- #include "lv_demos/src/lv_demo_widgets/lv_demo_widgets.h"
- #include "lv_drivers/win32drv/win32drv.h"
-
- #include
-
-
- /*********************
- * DEFINES
- *********************/
-
- /**********************
- * TYPEDEFS
- **********************/
-
- /**********************
- * STATIC PROTOTYPES
- **********************/
- static void hal_init(void);
- static int tick_thread(void *data);
-
- /**********************
- * STATIC VARIABLES
- **********************/
-
- /**********************
- * MACROS
- **********************/
-
- /**********************
- * GLOBAL FUNCTIONS
- **********************/
-
- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
- {
- /*Initialize LittlevGL*/
- lv_init();
-
- /*Initialize the HAL for LittlevGL*/
- lv_win32_init(hInstance, SW_SHOWNORMAL, 1024, 600, NULL);
-
- /*Output prompt information to the console, you can also use printf() to print directly*/
- LV_LOG_USER("LVGL initialization completed!");
- //printf("www.100ask.net: Lvgl initialization complete!\n");
-
-
- /*Run the demo*/
- //lv_100ask_demo_course_2_1_1(); // 基础对象(lv_obj),"Hello, LVGL!"
- //lv_100ask_demo_course_2_2_2(); // 基础对象的大小(size)
- //lv_100ask_demo_course_2_2_3(); // 基础对象的位置(position)
- //lv_100ask_demo_course_2_2_4(); // 基础对象的盒子模型(border-box)
- //lv_100ask_demo_course_2_2_5(); // 基础对象的样式(styles)
- lv_100ask_demo_course_2_2_6(); // 基础对象的事件(events)、事件冒泡
-
- //lv_100ask_demo_course_3_1_1(); // 组件(widgets): 标签(label)的用法
- //lv_100ask_demo_course_3_1_2(); // 组件(widgets): 标签(label),显示中文
- //lv_100ask_demo_course_3_2_1(); // 组件(widgets): 按钮(lv_btn)的用法
- //lv_100ask_demo_course_3_3_1(); // 组件(widgets): 使用物理按键代替触摸(groups)
- //lv_100ask_demo_course_3_4_1(); // 组件(widgets): 开关(lv_switch)的用法
- //lv_100ask_demo_course_3_5_1(); // 组件(widgets): 复选框(lv_checkbox)的用法
- //lv_100ask_demo_course_3_6_1(); // 组件(widgets): 下拉列表(lv_dropdown))的用法
- //lv_100ask_demo_course_3_7_1(); // 组件(widgets): 滚轮(lv_roller)的用法
- //lv_100ask_demo_course_3_8_1(); // 组件(widgets): 进度条(lv_bar)的用法
- //lv_100ask_demo_course_3_9_1(); // 组件(widgets): 进度条(lv_slider)的用法
- //lv_100ask_demo_course_3_10_1(); // 组件(widgets): 圆弧(lv_arc)的用法
- //lv_100ask_demo_course_3_10_3(); // 组件(widgets): 圆弧(lv_arc)-综合实战
- //lv_100ask_demo_course_3_11_1(); // 定时器: 定时器(lv_timer)的用法
- //lv_100ask_demo_course_3_11_2(); // 为什么创建出来的组件获取到的宽高是0?(在学习2_2_2时遇到的问题)
- //lv_100ask_demo_course_3_11_3(); // 为什么创建出来的组件获取到的坐标不正确?(在学习2_2_3时遇到的问题)
- //lv_100ask_demo_course_3_12_1(); // 组件(widgets): 线条(lv_line)的用法
- //lv_100ask_demo_course_3_12_2(); // 组件(widgets): 线条(lv_line)实战
- //lv_100ask_demo_course_3_13_1(); // 组件(widgets): 文本框(lv_textarea)的用法
- //lv_100ask_demo_course_3_14_1(); // 组件(widgets): 按钮矩阵(lv_btnmatrix)的用法
- //lv_100ask_demo_course_3_14_2(); // 组件(widgets): 按钮矩阵(lv_btnmatrix)和按钮(lv_btn)的对比(显示多个按钮谁更轻量级?)
-
- //lv_100ask_demo_course_6_1_1(); // 第三方库(lv_fs):通过LVGL文件系统接口统一不同的文件系统并读取文件、读取目录内容
-
-
- while(!lv_win32_quit_signal) {
- /* Periodically call the lv_task handler.
- * It could be done in a timer interrupt or an OS task too.*/
- lv_task_handler();
- usleep(10000); /*Just to let the system breath*/
- }
- return 0;
- }
大小(Size)
- //设置宽度
- lv_obj_set_width(obj, new_width);
- //设置高度:
- lv_obj_set_height(obj, new_height);
- //同时设置宽度、高度:
- lv_obj_set_size(obj, new_ width, new_ height);
获取大小(Get size)
- //获取宽度:
- lv_obj_get_width(obj);
- //获取高度:
- lv_obj_get_height(obj);
-
- void lv_100ask_demo_course_2_2_2(void)
- {
- lv_obj_t * obj = lv_obj_create(lv_scr_act());
- //lv_obj_set_width(obj, 300);
- //lv_obj_set_height(obj, 500);
- lv_obj_set_size(obj,600, 300);
-
- //printf("w:%d\n", lv_obj_get_width(obj));
- //printf("h:%d\n", lv_obj_get_height(obj));
- }
设置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); // position
参照父对象对齐:
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 lv_100ask_demo_course_2_2_3(void)
- {
- lv_obj_t * obj = lv_obj_create(lv_scr_act());
- //lv_obj_set_x(obj, 200);
- //lv_obj_set_y(obj, -50);
- //lv_obj_set_pos(obj, 100, 100);
- lv_obj_set_align(obj, LV_ALIGN_CENTER);
- //lv_obj_align(obj, LV_ALIGN_CENTER, 100, 100);
-
- lv_obj_t * label = lv_label_create(lv_scr_act());
- lv_label_set_text(label, "H!");
- lv_obj_align_to(label, obj, LV_ALIGN_OUT_LEFT_MID, 0, 0);
-
- //printf("w:%d\n", lv_obj_get_x(obj));
- //printf("h:%d\n", lv_obj_get_y(obj));
- }
- void lv_100ask_demo_course_2_2_4(void)
- {
- lv_obj_t * obj1 = lv_obj_create(lv_scr_act());
- lv_obj_align(obj1, LV_ALIGN_CENTER, 0, 0);
- lv_obj_set_style_border_width(obj1, 10, 0);
- lv_obj_set_style_outline_width(obj1, 10, 0);
-
- #if 0
- lv_obj_t * obj2 = lv_obj_create(lv_scr_act());
- lv_obj_t * obj_out_top = lv_obj_create(lv_scr_act());
- lv_obj_t * obj_out_bottom = lv_obj_create(lv_scr_act());
- lv_obj_t * obj_out_left = lv_obj_create(lv_scr_act());
- lv_obj_t * obj_out_right = lv_obj_create(lv_scr_act());
- //lv_obj_set_style_outline_width(obj_out_left, 10, 0);
-
- lv_obj_align(obj1, LV_ALIGN_CENTER, 0, 0);
- lv_obj_align_to(obj_out_top, obj1, LV_ALIGN_OUT_TOP_MID, 0, 0);
- lv_obj_align_to(obj_out_bottom, obj1, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
- lv_obj_align_to(obj_out_left, obj1, LV_ALIGN_OUT_LEFT_MID, 0, 0);
- lv_obj_align_to(obj_out_right, obj1, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
- lv_obj_align_to(obj2, obj_out_right, LV_ALIGN_OUT_TOP_MID, 0, 0);
- #endif
- }
-
-
- #endif /* LV_USE_100ASK_DEMO_COURSE_2_2_4 */
样式存储在 lv_style_t 变量中。样式变量应该是 静态 、全局或动态分配 的。 也就是它们不能是函数中的局部变量,因为当函数结束时它们会被销毁。样式初始化示例:
static lv_style_t style_obj;
lv_style_init(&style_obj);
当我们初始化好一个样式之后就可以设置它的样式属性了,接口函数是这样的格式: lv_style_set_
(&style, ); 示例:
lv_style_set_bg_color(&style_obj, lv_color_hex(0x000000)); // 设置背景色 lv_style_set_bg_opa(&style_obj, LV_OPA_50); // 设置背景透明度 lv_style_set_....
当我们初始化并且设置好一个样式之后就可以将它添加到对象上面了,接口函数只有一个: lv_obj_add_style(obj, &style,
) 参数 “obj” 就是要添加到的对象,“style” 是指向样式变量的指针,
是应添加样式的部分和状态的 OR-ed 值 (不能是互斥,否则就是清除标志,没法合并)。示例: lv_obj_add_style(obj, &style_obj, 0); // 默认(常用) lv_obj_add_style(obj, &style_obj, LV_STATE_PRESSED); // 在对象被按下时应用样式
我们可以获取属性的最终值(考虑级联、继承、本地样式和转换),接口函数是这样的格式:
lv_obj_get_style_
(obj, ); 函数使用对象的当前状态,如果没有更好的候选对象,则返回默认值。 例如:
lv_color_t color = lv_obj_get_style_bg_color(obj, LV_PART_MAIN);
删除对象的所有样式:
lv_obj_remove_style_all(obj);
删除对象的特定样式:
lv_obj_remove_style(obj, &style_obj, selector);
只有当 selector 与 lv_obj_add_style 中使用的 selector 匹配时,此函数才会删除 style 如果 style 是空,那么会根据给出的 selector 检查并删除所有匹配的样式 如果 selector 是 LV_STATE_ANY 或 LV_PART_ANY 就会删除具有任何状态或部分的样式。下面这个效果和lv_obj_remove_style_all 的效果是一样的:
lv_obj_remove_style(obj, NULL, LV_STATE_ANY | LV_PART_ANY );
所有的可用的样式属性我们可以在文档或者代码中获取得到。
文档位置:
英文原版:https://docs.lvgl.io/8.1/overview/style-props.html
中文翻译:http://lvgl.100ask.net/8.1/overview/style-props.html
代码位置:
普通样式:lvgl/src/misc/lv_style_gen.h
本地样式:lvgl/src/core/lv_obj_style_gen.h
文档位置和代码位置可能在后续的版本更新中会发生变化,这里的方法只是提供参考,不需要死记硬背函数接口名。
背景属性和我们前面学习的盒子模型关系很大,背景属性主要有一下这些:
对象可以处于以下状态的组合:
LV_STATE_DEFAULT (0x0000) 正常,释放状态
LV_STATE_CHECKED (0x0001) 切换或检查状态
LV_STATE_FOCUSED (0x0002) 通过键盘或编码器聚焦或通过触摸板/鼠标点击 LV_STATE_FOCUS_KEY (0x0004) 通过键盘或编码器聚焦,但不通过触摸板/鼠标聚焦 LV_STATE_EDITED (0x0008) 由编码器编辑
LV_STATE_HOVERED (0x0010) 鼠标悬停(现在不支持)
LV_STATE_PRESSED (0x0020) 被按下
LV_STATE_SCROLLED (0x0040) 正在滚动
LV_STATE_DISABLED (0x0080) 禁用状态
LV_STATE_USER_1 (0x1000) 自定义状态
LV_STATE_USER_2 (0x2000) 自定义状态
LV_STATE_USER_3 (0x4000) 自定义状态
LV_STATE_USER_4 (0x8000) 自定义状态
这些可能会随着lvgl的更新而不断增加,同学们可以阅读最新版本的文档获取最新资料。
对象可以有 部分(parts) ,它们也可以有自己的样式。LVGL 中存在以下预定义部分:
LV_PART_MAIN 类似矩形的背景
LV_PART_SCROLLBAR 滚动条
LV_PART_INDICATOR 指标,例如用于滑块、条、开关或复选框的勾选框 LV_PART_KNOB 像手柄一样可以抓取调整值
LV_PART_SELECTED 表示当前选择的选项或部分
LV_PART_ITEMS 如果小部件具有多个相似元素(例如表格单元格)
LV_PART_TICKS 刻度上的刻度,例如对于图表或仪表
LV_PART_CURSOR 标记一个特定的地方,例如文本区域或图表的光标
LV_PART_CUSTOM_FIRST 可以从这里添加自定义部件。
这些可能会随着lvgl的更新而不断增加,同学们可以阅读最新版本的文档获取最新资料。
除了“普通” 样式外,对象还可以存储 本地样式(私有样式) 。
本地样式与普通样式类似,但是它不能在其他对象之间共享。如果使用本地样式,将自动分配局部样式,并在删除对象时释放。本地样式对于向对象添加本地自定义很有用。
本地样式的接口函数是这样的格式:
lv_obj_set_style_
(obj, , ); 示例:
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffff), 0); // 设置背景色 lv_obj_set_style_bg_opa(obj, LV_OPA_50, 0); // 设置背景透明度 lv_style_set_style_....
删除本地样式的时候我们删除某一个样式:
lv_obj_remove_local_style_prop(obj, LV_STYLE_..., selector);
LV_STYLE_...的取值请看: lvgl/src/misc/lv_style.h 中的 lv_style_prop_t
某些属性(通常与文本相关)可以从父对象的样式继承。 只有没有在为对象设置样式属性的时候,才应用继承。 在这种情况下,如果这个属性是可继承的,那这个属性的值会在父类中检索,直到一个对象为该属性指定了一个值。父类将使用自己的状态来确定该值。 因此,如果按下按钮,并且文本颜色来自此处,则将使用按下的文本颜色。
- static void lv_example_slider_2(void)
- {
- /*Create a transition*/
- static const lv_style_prop_t props[] = {LV_STYLE_BG_COLOR, 0};
- static lv_style_transition_dsc_t transition_dsc;
- lv_style_transition_dsc_init(&transition_dsc, props, lv_anim_path_linear, 300, 0, NULL);
-
- static lv_style_t style_main; // 矩形背景部分
- static lv_style_t style_indicator; // 指针部分
- static lv_style_t style_knob; // 旋钮部分
- static lv_style_t style_pressed_color; // 对象某部分被按下时,该部分样式应用的颜色
-
- // 矩形背景部分
- lv_style_init(&style_main);
- lv_style_set_bg_opa(&style_main, LV_OPA_COVER);
- lv_style_set_bg_color(&style_main, lv_color_hex3(0xbbb));
- //lv_style_set_outline_width(&style_main, 5);
- //lv_style_set_border_width(&style_main, 2);
- lv_style_set_radius(&style_main, LV_RADIUS_CIRCLE);
- lv_style_set_pad_ver(&style_main, -2); /*Makes the indicator larger*/
-
- // 指针部分
- lv_style_init(&style_indicator);
- lv_style_set_bg_opa(&style_indicator, LV_OPA_COVER);
- lv_style_set_bg_color(&style_indicator, lv_palette_main(LV_PALETTE_CYAN));
- lv_style_set_radius(&style_indicator, LV_RADIUS_CIRCLE);
- lv_style_set_transition(&style_indicator, &transition_dsc);
-
- // 旋钮部分
- lv_style_init(&style_knob);
- lv_style_set_bg_opa(&style_knob, LV_OPA_COVER);
- lv_style_set_bg_color(&style_knob, lv_palette_main(LV_PALETTE_CYAN));
- lv_style_set_border_color(&style_knob, lv_palette_darken(LV_PALETTE_CYAN, 3));
- lv_style_set_border_width(&style_knob, 2);
- lv_style_set_radius(&style_knob, LV_RADIUS_CIRCLE);
- lv_style_set_pad_all(&style_knob, 6); /*Makes the knob larger*/
- lv_style_set_transition(&style_knob, &transition_dsc);
-
- // 对象某部分被按下时,该部分样式应用的颜色
- lv_style_init(&style_pressed_color);
- lv_style_set_bg_color(&style_pressed_color, lv_palette_darken(LV_PALETTE_CYAN, 2));
-
- /*Create a slider and add the style*/
- lv_obj_t * slider = lv_slider_create(lv_scr_act());
-
- // 体验流程:先体验 lv_obj_add_style 都被注释时的效果;然后一个个去掉注释
- lv_obj_remove_style_all(slider); // 删除对象的所有样式,然后下面再添加我们自定义的样式
- lv_obj_add_style(slider, &style_main, LV_PART_MAIN); // 矩形背景部分
- lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR); // 指针部分
- lv_obj_add_style(slider, &style_pressed_color, LV_PART_INDICATOR | LV_STATE_PRESSED); // 当指针部分被按下的时候,指针部分应用该样式
- lv_obj_add_style(slider, &style_knob, LV_PART_KNOB); // 旋钮部分,像按钮一样可以抓取调整值
- lv_obj_add_style(slider, &style_pressed_color, LV_PART_KNOB | LV_STATE_PRESSED); // 当旋钮部分被按下的时候,旋钮部分应用该样式
-
- lv_obj_center(slider);
- }
-
- void lv_100ask_demo_course_2_2_5(void)
- {
-
- // 正常样式
- static lv_style_t style_obj;
-
- lv_style_init(&style_obj);
- lv_style_set_bg_color(&style_obj, lv_color_hex(0x000000)); // 设置背景色
- lv_style_set_text_color(&style_obj, lv_color_hex(0xc43e1c)); // 设置文字颜色
- //lv_style_set_bg_color(&style_obj, lv_color_hex(0xc43e1c)); // 设置背景色
- //lv_style_set_bg_opa(&style_obj, 30); // 设置透明度
-
- // 创建对象
- lv_obj_t * obj = lv_obj_create(lv_scr_act());
-
- lv_obj_t * obj2 = lv_obj_create(lv_scr_act());
- //lv_obj_align(obj2, LV_ALIGN_CENTER, 0 ,0);
-
- // 本地样式
- //lv_obj_set_style_bg_color(obj, lv_color_hex(0xc43e1c), LV_STATE_PRESSED); // 设置背景色
- //lv_obj_set_style_bg_color(obj2, lv_color_hex(0xc43e1c), LV_STATE_PRESSED); // 设置背景色
- //lv_obj_set_style_bg_opa(obj, LV_OPA_50, 0); // 设置背景透明度
-
- // 添加样式到对象
- lv_obj_add_style(obj, &style_obj, 0); // 默认状态: LV_STATE_DEFAULT
- lv_obj_add_style(obj2, &style_obj, 0); // 默认状态: LV_STATE_DEFAULT
- lv_obj_add_style(obj, &style_obj, LV_STATE_PRESSED); // 按下状态,当对象被按下的时候应用该样式
- lv_obj_add_style(obj2, &style_obj, LV_STATE_PRESSED); // 按下状态,当对象被按下的时候应用该样式
-
-
-
- // 滑杆示例(不需要深入研究,体会部件样式的部分和状态即可),看里面的注释:体验流程
- //lv_example_slider_2();
- }
-
-
- #endif /* LV_USE_100ASK_DEMO_COURSE_2_2_5 */
当发生用户可能感兴趣的事情时,LVGL 中会触发事件,例如当一个对象:
lv_obj_add_event_cb(obj, event_cb, event_code, user_data);
lv_event_send(obj, event_cb, event_code, user_data);
lv_obj_remove_event_cb(obj, event_cb); lv_obj_remove_event_dsc(obj, event_dsc); //event_dsc 是 lv_obj_add_event_cb 返回的指针
更全面的信息请查阅:
源码:lvgl/src/core/lv_event.h (lv_event_code_t)
开发文档:
英文:https://docs.lvgl.io/8.1/overview/event.html#event-codes
中文:http://lvgl.100ask.net/8.1/overview/event.html#event-codes
事件回调函数只有一个参数,这个参数对我们的作为非常大,现在的版本提供这些功能:
static void my_event_cb(lv_event_t * event);
获取触发的事件代码:
lv_event_code_t code = lv_event_get_code(e);
获取触发事件的对象:
lv_obj_t * target = lv_event_get_target(e);
获取最初触发事件的对象(事件冒泡):
lv_obj_t * target = lv_event_get_current_target(e);
获取事件传递的用户数据:
lv_event_get_user_data(e); 获取使用 lv_obj_add_event_cb 传递的用户数据 lv_event_get_param(e); 获取使用 lv_event_send 传递的用户数据
一个事件回调函数可给多个对象使用
我们创建了一个事件处理函数之后是可以给不同的对象使用的。
一个对象可以使用多个事件回调函数
我们创建的对象可以绑定多个事件,比如一个事件是处理点击类型的事件,一个事件处理按下类型的事件等等。
如果传入的用户数据不一样,一个对象可以绑定同一个事件回调函数多次,事件将按照添加的顺序调用。例如:
lv_obj_add_event_cb(obj, my_clicked_event_cb, LV_EVENT_CLICKED, &num1); lv_obj_add_event_cb(obj, my_clicked_event_cb, LV_EVENT_CLICKED, &num2);
如果对象启用了 lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE),该对象的所有事件将会发送到该对象的父级。如果父级也启用了 LV_OBJ_FLAG_EVENT_BUBBLE,那么事件继续发送到他的父级,依此类推。
lv_event_get_target(e); 获取触发事件的当前对象。
lv_event_get_current_target(e); 获取事件冒泡的父对象。
- #if 0
- static void my_event_cb(lv_event_t * e)
- {
- lv_obj_t * obj = lv_event_get_target(e); // 获取触发事件的部件(对象)
- lv_event_code_t code = lv_event_get_code(e); // 获取当前部件(对象)触发的事件代码
- lv_obj_t * label = lv_event_get_user_data(e); // 获取添加事件时传递的用户数据
-
- switch(code){
- case LV_EVENT_PRESSED:
- lv_label_set_text(label, "LV_EVENT_PRESSED");
- lv_obj_set_style_bg_color(obj, lv_color_hex(0xc43e1c), 0); // 通过本地样式(私有样式)设置背景色
- printf("LV_EVENT_PRESSED\n");
- break;
- case LV_EVENT_LONG_PRESSED:
- lv_label_set_text(label, "LV_EVENT_LONG_PRESSED");
- lv_obj_set_style_bg_color(obj, lv_color_hex(0x4cbe37), 0); // 通过本地样式(私有样式)设置背景色
- printf("LV_EVENT_LONG_PRESSED\n");
- break;
- default:
- //printf("NONE\n");
- break;
- }
- }
-
- void lv_100ask_demo_course_2_2_6(void)
- {
- /* 创建基础部件(对象) */
- lv_obj_t * obj = lv_obj_create(lv_scr_act());
-
- /* 创建label部件(对象) */
- lv_obj_t * label = lv_label_create(lv_scr_act());
- lv_label_set_text(label, "test"); // 设置label展示的文字
- lv_obj_center(label); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:lv_scr_act()
-
- // 为obj1添加事件回调函数,所有的事件类型都能触发该回调函数
- lv_obj_add_event_cb(obj, my_event_cb, LV_EVENT_ALL, label);
- }
- #endif // 0
-
-
-
- /* 事件冒泡 */
- #if 1
- static void my_event_cb(lv_event_t * e)
- {
- lv_obj_t * obj = lv_event_get_target(e); // 获取触发事件的对象
- lv_obj_t * parent = lv_event_get_current_target(e); // 获取触发事件对象的父对象(事件冒泡才有)
- lv_event_code_t code = lv_event_get_code(e); // 获取当前部件触发的事件代码
- lv_obj_t * label = lv_event_get_user_data(e); // 获取添加事件时传递的用户数据
-
- switch(code){
- case LV_EVENT_PRESSED:
- lv_label_set_text(label, "LV_EVENT_PRESSED");
- lv_obj_set_style_bg_color(parent, lv_color_hex(0xc43e1c), 0); // 通过本地样式(私有样式)设置背景色
- lv_obj_set_style_bg_color(obj, lv_color_hex(0xc43e1c), 0); // 通过本地样式(私有样式)设置背景色
- printf("LV_EVENT_PRESSED\n");
- break;
- case LV_EVENT_CLICKED:
- lv_label_set_text(label, "LV_EVENT_CLICKED");
- lv_obj_remove_local_style_prop(parent, LV_STYLE_BG_COLOR, 0); // 删除通过本地样式(私有样式)设置的背景色
- lv_obj_remove_local_style_prop(obj, LV_STYLE_BG_COLOR, 0); // 删除通过本地样式(私有样式)设置的背景色
- printf("LV_EVENT_CLICKED\n");
- break;
- default:
- //printf("NONE\n");
- break;
- }
- }
-
- void lv_100ask_demo_course_2_2_6(void)
- {
- /* 创建一个基础对象 obj1 */
- lv_obj_t * obj1 = lv_obj_create(lv_scr_act());
- lv_obj_set_size(obj1, 450, 250);
- lv_obj_center(obj1); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:lv_scr_act()
-
- /* 以 obj1 创建一个基础对象 obj2 */
- lv_obj_t * obj2 = lv_obj_create(obj1);
- lv_obj_set_size(obj2, 400, 200);
- lv_obj_center(obj2); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:obj1
- lv_obj_add_flag(obj2, LV_OBJ_FLAG_EVENT_BUBBLE); // 启用事件冒泡,将接收到的所有事件传播给父级
-
- /* 以 obj2 创建一个基础对象 obj3 */
- lv_obj_t * obj3 = lv_obj_create(obj2);
- lv_obj_set_size(obj3, 350, 150);
- lv_obj_center(obj3); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:obj2
- lv_obj_add_flag(obj3, LV_OBJ_FLAG_EVENT_BUBBLE); // 启用事件冒泡,将接收到的所有事件传播给父级
-
- /* 以 obj3 创建一个基础对象 obj4 */
- lv_obj_t * obj4 = lv_obj_create(obj3);
- lv_obj_set_size(obj4, 300, 100);
- lv_obj_center(obj4); // 将对象与其父对象的中心对齐,这里的父对象是屏幕:obj3
- lv_obj_add_flag(obj4, LV_OBJ_FLAG_EVENT_BUBBLE); // 启用事件冒泡,将接收到的所有事件传播给父级
-
- /* 以屏幕为父类,创建一个label部件(对象) */
- lv_obj_t * label = lv_label_create(lv_scr_act());
- lv_label_set_text(label, "test"); // 设置label展示的文字
- lv_obj_align_to(label, obj1, LV_ALIGN_OUT_TOP_MID, 0, 0); // 将label相对于obj1对齐
-
- // 将给obj1添加事件回调函数,所有的事件类型都能触发该回调函数
- lv_obj_add_event_cb(obj2, my_event_cb, LV_EVENT_ALL, label);
- }
- #endif // 1
-
- #endif /* LV_USE_100ASK_DEMO_COURSE_2_2_6 */