提示:本博客作为学习笔记,有错误的地方希望指正
文章目录
一、btn 简介
1.1概述 Overview
默认情况下,按钮在以下几点与 Base 对象不同:
•不可滚动
•添加到默认组
• 它的默认高度和宽度是 LV_SIZE_CONTENT
1.2部分和风格 Parts and Styles
LV_PART_MAIN按钮的背景。它使用典型的背景样式属性。
1.3使用 Usage
与Base object相比没有新功能
1.4事件 Events
LV_EVENT_VALUE_CHAN . GED当LV_OBJ_FLAG_CHECKABLE标志被启用并且对象被点击时(转换到/从选中状态)
1.5按键 Keys
如果LV_OBJ_FLAG_CHECKABLE启用LV_KEY_RIGHT和LV_KEY_UP使对象检查,LV_KEY_LEFT并LV_KEY_DOWN使得它选中。请注意,状态LV_KEY_ENTER被转换为LV_EVENT_PRESSED/PRESSING/RELEASED等。
二、Label API
2.1 Btn API
其中btn的函数比较少,示例中使用到回调事件,我们从回调事件分析整个流程。
lv_obj_t * lv_btn_create(lv_obj_t * parent); //创建按键对象
2.2 LVGL的状态标志位的处理API和Flags
有一些标志可以在对象上使用,以影响他们的行为与布局,Flags类型如下
LV_OBJ_FLAG_HIDDEN /**<使对象隐藏。(就像它根本不存在)*/
LV_OBJ_FLAG_CLICKABLE /**<使对象可点击的输入设备*/
LV_OBJ_FLAG_CLICK_FOCUSABLE /**<添加聚焦状态到对象时点击*/
LV_OBJ_FLAG_CHECKABLE /**<当单击对象时切换检查状态*/
LV_OBJ_FLAG_SCROLLABLE /**<使对象可滚动*/
LV_OBJ_FLAG_SCROLL_ELASTIC /**<允许内部滚动,但速度较慢*/
LV_OBJ_FLAG_SCROLL_MOMENTUM /**<使对象在“抛出”时进一步滚动*/
LV_OBJ_FLAG_SCROLL_ONE /**<只允许滚动一个可snap子元素*/
LV_OBJ_FLAG_SCROLL_CHAIN /**<允许传播滚动到父*/
LV_OBJ_FLAG_SCROLL_ON_FOCUS /**<自动滚动对象,使其在聚焦时可见*/
LV_OBJ_FLAG_SNAPPABLE /**<如果滚动捕捉是在父对象上启用,它可以捕捉到这个对象*/
LV_OBJ_FLAG_PRESS_LOCK /**<保持物体被压,即使从物体滑出*/
LV_OBJ_FLAG_EVENT_BUBBLE /**<传播事件到父*/
LV_OBJ_FLAG_GESTURE_BUBBLE /**<传播手势到父*/
LV_OBJ_FLAG_ADV_HITTEST /**<允许执行更准确的命中(点击)测试。例如,考虑圆角*/
LV_OBJ_FLAG_IGNORE_LAYOUT /**<使对象可以被布局*/
LV_OBJ_FLAG_FLOATING /**<当父对象滚动并忽略布局时,不要滚动对象*/
LV_OBJ_FLAG_LAYOUT_1 /**<自定义标志,自由使用的布局*/
LV_OBJ_FLAG_LAYOUT_2 /**<自定义标志,自由使用的布局*/
LV_OBJ_FLAG_WIDGET_1 /**<自定义标志,自由使用由小部件*/
LV_OBJ_FLAG_WIDGET_2 /**<自定义标志,自由使用由小部件*/
LV_OBJ_FLAG_USER_1 /**<自定义标志,可由用户*/
LV_OBJ_FLAG_USER_2 /**<自定义标志,可由用户*/
LV_OBJ_FLAG_USER_3 /**<自定义标志,可由用户*/
LV_OBJ_FLAG_USER_4 /**<自定义标志,可由用户*/
对象API如下
void lv_init(void) //初始化lvgl
void lv_deinit(void) //反初始化lvgl
bool lv_is_initialized(void) //返回“lv”库当前是否初始化
lv_obj_t * lv_obj_create(lv_obj_t * parent) //创建一个基础对象(一个矩形)·
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) //设置一个或多个标志
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f) //清除一个或多个标志位
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) //添加一个或多个状态到对象。其他状态位保持不变如果在样式中指定,过渡动画将从以前的状态开始到当前状态。
void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state) //移除对象的一个或多个状态。其他状态位保持不变。如果在样式中指定,过渡动画将从以前的状态开始到当前状态。
static inline void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) //设置对象的user_data字段
bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f) //检查一个对象上是否设置了一个或所有的给定标志。
bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f) //检查一个对象上是否设置了一个给定的标志或任何一个标志。
lv_state_t lv_obj_get_state(const lv_obj_t * obj) //获取一个对象的状态
bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state) //检查对象是否处于给定状态。
void * lv_obj_get_group(const lv_obj_t * obj); //获取对象的组
static inline void * lv_obj_get_user_data(lv_obj_t * obj) //获取对象的user_data字段
void lv_obj_allocate_spec_attr(lv_obj_t * obj) //获取对象的user_data字段
bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p)//检查对象的类型。
bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p) //检查任何对象是否具有给定的类(类型)。
const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj) //获取对象的类(类型)
bool lv_obj_is_valid(const lv_obj_t * obj) //检查是否有任何对象仍然“活着”。
static inline lv_coord_t lv_obj_dpx(const lv_obj_t * obj, lv_coord_t n) //缩放给定的像素数(距离或大小)相对于160 DPI显示考虑对象显示的DPI。
2.3 LVGL的事件回调函数
/**
*为对象添加一个事件处理函数。
*由用户用于响应与对象一起发生的事件。
*一个对象可以有多个事件处理程序。调用它们的顺序与添加它们的顺序相同。
* @param obj对象指针
* @param过滤器和事件代码(例如。' LV_EVENT_CLICKED '),该事件应该被调用。' LV_EVENT_ALL '可以被起诉接收所有事件。
* @param event_cb新的事件函数
* @param user_data自定义数据数据将在' event_cb '中可用
* @返回事件描述符的指针。可以在::lv_obj_remove_event_dsc
*/
Struct _lv_event_dsc_t * lv_obj_add_event_cb(Struct _lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter,void * user_data);
上述的是对于LVGL事件回调函数的参数介绍,其中 event_cb 作为事件回调,可以自定义其函数,接下来对这个回调函数的说明,static void event_btn_handler(lv_event_t *e)作为自定义回调函数其中回调函数的参数是 lv_event_t类型的结构体,这个结构体包含几个成员变量。
typedef struct _lv_event_t {
struct _lv_obj_t * target; //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
struct _lv_obj_t * current_target; //获取事件的当前目标。它是被调用事件处理程序的对象。
lv_event_code_t code; //获取事件的事件代码
void * user_data; //获取在对象上注册事件时传递的user_data
void * param; //当事件被发送时,获取参数传递
struct _lv_event_t * prev;
uint8_t deleted : 1;
} lv_event_t;
Lv_event_t是传递给事件回调的唯一参数,它包含关于事件的所有数据。以下值可以从它中获得:
lv_event_get_code(e) //获取事件代码
lv_event_get_target(e) //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
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的最后一个参数传递的参数
2.4 LVGL事件API以及事件分类
事件的分类
事件代码可以分为以下几类:
• 输入设备的事件
• 绘画事件
• 其他事件
• 特殊事件
• 自定义事件
LV_EVENT_ALL = 0, /**<对象所有事件*/
/**输入设备事件*/
LV_EVENT_PRESSED, /**<对象已被按下*/
LV_EVENT_PRESSING, /**<对象正在被按下(按下时连续调用)*/
LV_EVENT_PRESS_LOST, /**<对象仍在被按下,但将光标/手指滑离对象*/
LV_EVENT_SHORT_CLICKED, /**<对象被短时间的按下,然后释放。不调用,如果滚动*/
LV_EVENT_LONG_PRESSED, /**<对象至少被按下' long_press_time '。不调用,如果滚动*/
LV_EVENT_LONG_PRESSED_REPEAT, /**<在每个`long_press_repeat_time`中`long_press_time`之后调用ms.如果滚动则不调用。*/
LV_EVENT_CLICKED, /**<释放时调用如果没有滚动(无论长按)*/
LV_EVENT_RELEASED, /**<在每次对象被释放时调用*/
LV_EVENT_SCROLL_BEGIN, /**<滚动开始*/
LV_EVENT_SCROLL_END, /**<滚动结束*/
LV_EVENT_SCROLL , /**< 滚动*/
LV_EVENT_GESTURE, /**<检测到手势。使用“lv_indev_get_gesture_dir(lv_indev_get_act())”获得手势*/
LV_EVENT_KEY, /**<一个key被发送到对象。用' lv_indev_get_key(lv_indev_get_act())); '获得键*/
LV_EVENT_FOCUSED, /**<对象被聚焦*/
lv_event_DEFOCUSED, /**<对象离焦*/
LV_EVENT_LEAVE, /**<对象被散焦但仍然被选中*/
LV_EVENT_HIT_TEST, /**<执行高级命中测试*/
* / / * *绘制事件*/
LV_EVENT_COVER_CHECK, /**<检查对象是否完全覆盖了一个区域。事件参数是' lv_cover_check_info_t '*/
lv_event_REFR_ext_draw_size, /**<获得对象周围所需的额外绘制区域(例如阴影)。event参数是' lv_coord_t * '来存储大小*/
LV_EVENT_DRAW_MAIN_BEGIN, /**<开始主绘图阶段*/
LV_EVENT_DRAW_MAIN, /**<执行主绘图*/
LV_EVENT_DRAW_MAIN_END, /**<完成主绘图阶段*/
LV_EVENT_DRAW_POST_BEGIN, /**<开始post绘制阶段(当所有子元素绘制完成时)*/
LV_EVENT_DRAW_POST, /**<执行post绘制阶段(当所有子元素都绘制时)*/
LV_EVENT_DRAW_POST_END, /**<完成post绘制阶段(当所有子元素都绘制时)*/
LV_EVENT_DRAW_PART_BEGIN, /**<开始绘制零件。事件参数是' lv_obj_draw_dsc_t * '。*/
LV_EVENT_DRAW_PART_END, /**<绘制零件结束。事件参数是' lv_obj_draw_dsc_t * '。*/
* / / * *特别事件*/
LV_EVENT_VALUE_CHANGED, /**<对象的值已经改变(即滑块移动)*/
LV_EVENT_INSERT, /**<将文本插入到对象中。事件数据是' char * '正在插入*/
LV_EVENT_REFRESH, /**<通知对象刷新其上的某些内容(为用户)*/
LV_EVENT_READY, /**<进程已完成*/
LV_EVENT_CANCEL, /**<进程已被取消*/
* / / * *其他事件*/
LV_EVENT_DELETE, /**<对象正在被删除*/
LV_EVENT_CHILD_CHANGED, /**< Child was removed/added*/
LV_EVENT_SIZE_CHANGED, /**<对象坐标/大小已更改*/
LV_EVENT_STYLE_CHANGED, /**<对象的样式已更改*/
LV_EVENT_LAYOUT_CHANGED, /**<子节点的位置由于布局重新计算而改变*/
LV_EVENT_GET_SELF_SIZE, /**<获取小部件的内部大小*/
_LV_EVENT_LAST /**默认事件个数*/
事件的API
lv_res_t lv_event_send(lv_obj_t * obj, lv_event_code_t event_code, void * param) //发送一个事件给对象
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e) //由小部件内部使用,调用祖先小部件类型的事件处理程序
lv_obj_t * lv_event_get_target(lv_event_t * e) //获得事件最初瞄准的对象。即使事件是冒泡的,也是一样的。
lv_obj_t * lv_event_get_current_target(lv_event_t * e) //获取事件的当前目标。它是被调用事件处理程序的对象。
lv_event_code_t lv_event_get_code(lv_event_t * e) //获取事件的事件代码
void * lv_event_get_param(lv_event_t * e) //当事件被发送时,获取参数传递
void * lv_event_get_user_data(lv_event_t * e) //获取在对象上注册事件时传递的user_data
uint32_t lv_event_register_id(void) //注册一个新的自定义事件ID。
void _lv_event_mark_deleted(lv_obj_t * obj) //可以调用嵌套事件,其中一个可能属于正在删除的对象。
struct _lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data) //为对象添加一个事件处理函数。
bool lv_obj_remove_event_dsc(lv_obj_t * obj, struct _lv_event_dsc_t * event_dsc) //移除一个对象的事件处理函数。
lv_indev_t * lv_event_get_indev(lv_event_t * e) //获取作为参数传递给indev相关事件的输入设备。
lv_obj_draw_part_dsc_t * lv_event_get_draw_part_dsc(lv_event_t * e) //获得零件绘制描述符作为参数传递到' LV_EVENT_DRAW_PART_BEGIN/END '。
const lv_area_t * lv_event_get_clip_area(lv_event_t * e) //获取剪辑区域作为参数来绘制事件事件。
const lv_area_t * lv_event_get_old_size(lv_event_t * e) //获取对象改变大小之前的旧区域。可以在' LV_EVENT_SIZE_CHANGED '中使用
uint32_t lv_event_get_key(lv_event_t * e) //获取作为参数传递给事件的密钥。可以在' LV_EVENT_KEY '中使用
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e) //获取滚动的动画描述符。可以在' LV_EVENT_SCROLL_BEGIN '中使用
void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size) //设置新的额外绘制尺寸。可以在' lv_event_ref_ext_draw_size '中使用
lv_point_t * lv_event_get_self_size_info(lv_event_t * e) //获取一个指向' lv_point_t '变量的指针,其中自我大小应该保存(宽度在' point->x '和高度' point->y ')。
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e) //获取一个指向' lv_hit_test_info_t '变量的指针,该变量将保存命中测试结果。可以在' LV_EVENT_HIT_TEST '中使用
const lv_area_t * lv_event_get_cover_area(lv_event_t * e) //获取一个指向区域的指针,该区域应该被检查对象是否完全覆盖它。
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res) //设置封面检查的结果。可以在' LV_EVENT_COVER_CHECK '中使用
三、示例
3.1示例实现按键回调显示
/*************************************************
* 函数名称 : event_btn1_handler
* 参 数 : 回调参数
* 函数功能 : btn事件回调函数
*************************************************/
static void event_btn_handler(lv_event_t* e)
{
lv_event_code_t code = lv_event_get_code(e); //获取回调事件
if (code == LV_EVENT_CLICKED) { //点击事件
printf("Clicked\n\r");
}
else if (code == LV_EVENT_VALUE_CHANGED){ //对象的值已经改变
printf("Toggled");
}
}
/*************************************************
* 函数名称 : Btn_show_1
* 参 数 : 无
* 函数功能 : 按键显示
*************************************************/
void Btn_show_1()
{
lv_obj_t* label; //创建label
lv_obj_t* btn1 = lv_btn_create(lv_scr_act()); //创建btn
lv_obj_add_event_cb(btn1, event_btn_handler, LV_EVENT_ALL, NULL); //创建按键回调函数
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40); //居中对象
label = lv_label_create(btn1); //创建label
lv_label_set_text(label, "Button1"); //设置label字内容
lv_obj_t* btn2 = lv_btn_create(lv_scr_act()); //创建按键
lv_obj_add_event_cb(btn2, event_btn_handler, LV_EVENT_ALL, NULL); //创建按键回调函数
lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40); //居中对象
lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE); //添加标志位 /**<当单击对象时切换检查状态*/
lv_obj_set_height(btn2, LV_SIZE_CONTENT); //设置对象的高度
label = lv_label_create(btn2); //创建label
lv_label_set_text(label, "Toggle"); //设置label的字内容
lv_obj_center(label); //居中对象
}
3.2示例实现动画显示
/*************************************************
* 函数名称 : Btn_show_2
* 参 数 : 无
* 函数功能 : 按键显示
*************************************************/
void Btn_show_2()
{
static lv_style_t style; //创建
lv_style_init(&style); //创建label
lv_style_set_radius(&style,3); //设置样式圆角
lv_style_set_bg_opa(&style,LV_OPA_100); //设置样式透明度
lv_style_set_bg_color(&style,lv_palette_main(LV_PALETTE_BLUE)); //设置背景颜色
lv_style_set_bg_grad_color(&style,lv_palette_darken(LV_PALETTE_BLUE,2));//设置下半背景颜色
lv_style_set_bg_grad_dir(&style,LV_GRAD_DIR_VER); //设置背景颜色方向
lv_style_set_border_opa(&style,LV_OPA_40); //设置边框透明度
lv_style_set_border_width(&style,2); //设置边框宽度
lv_style_set_border_color(&style,lv_palette_main(LV_PALETTE_GREY)); //设置边框颜色
lv_style_set_shadow_width(&style,8); //设置阴影宽度
lv_style_set_shadow_color(&style,lv_palette_main(LV_PALETTE_GREY)); //设置阴影颜色
lv_style_set_shadow_ofs_y(&style,8); //设置阴影偏移部分
lv_style_set_outline_opa(&style,LV_OPA_COVER); //设置外轮廓透明度
lv_style_set_outline_color(&style,lv_palette_main(LV_PALETTE_BLUE)); //设置外罗阔颜色
lv_style_set_text_color(&style, lv_color_white()); //字体颜色
lv_style_set_pad_all(&style,10); //设置边距
static lv_style_t style_pr; //创建按压样式
lv_style_init(&style_pr); //初始化样式
lv_style_set_outline_width(&style_pr,30); //设置样式外轮廓初始化
lv_style_set_outline_opa(&style_pr,LV_OPA_TRANSP); //设置样式外轮廓透明度
lv_style_set_translate_y(&style_pr,5); //变换y轴
lv_style_set_shadow_ofs_y(&style_pr,3); //变换x轴
lv_style_set_bg_color(&style_pr,lv_palette_darken(LV_PALETTE_BLUE,4)); //设置背景颜色
static lv_style_transition_dsc_t trans; //创建变换对象
static lv_style_prop_t props[] = {LV_STYLE_OUTLINE_WIDTH,LV_STYLE_OUTLINE_OPA,0}; //变换位置
lv_style_transition_dsc_init(&trans,props,lv_anim_path_linear,300,0,NULL); //初始化变换
lv_style_set_transition(&style_pr,&trans); //设置变换
lv_obj_t * btn1 = lv_btn_create(lv_scr_act()); //创建按键变量
lv_obj_remove_style_all(btn1); //移除所有样式
lv_obj_add_style(btn1,&style,0); //添加样式
lv_obj_add_style(btn1,&style_pr,LV_STATE_PRESSED); //添加样式
lv_obj_set_size(btn1,LV_SIZE_CONTENT,LV_SIZE_CONTENT); //设置对象的尺寸
lv_obj_center(btn1); //居中对象
lv_obj_t * label = lv_label_create(btn1); //创建Label
lv_label_set_text(label,"Button"); //设置Label内容
lv_obj_center(label); //居中显示
}
3.3示例实现按键果冻显示
/*************************************************
* 函数名称 : Btn_show_3
* 参 数 : 无
* 函数功能 : 果冻案件,实现类似果冻效果的按键样式
*************************************************/
void Btn_show_3()
{
static lv_style_transition_dsc_t transition_dsc_def; //创建变换对象
//变换位置
static lv_style_prop_t props[] = {LV_STYLE_TRANSFORM_WIDTH,LV_STYLE_TRANSFORM_HEIGHT,LV_STYLE_TEXT_LETTER_SPACE,0};
//初始化变换
lv_style_transition_dsc_init(&transition_dsc_def,props,lv_anim_path_overshoot,250,100,NULL);
static lv_style_transition_dsc_t transition_dsc_pr; //创建变换对象
//初始化变换
lv_style_transition_dsc_init(&transition_dsc_pr,props,lv_anim_path_ease_in_out,250,0,NULL);
static lv_style_t style_def; //创建样式
lv_style_init(&style_def); //初始化样式
lv_style_set_transition(&style_def,&transition_dsc_def); //设置样式转换
static lv_style_t style_pr; //设置样式
lv_style_init(&style_pr); //初始化样式
lv_style_set_transform_width(&style_pr,10); //样式变换
lv_style_set_transform_height(&style_pr,-10); //样式变换
lv_style_set_transition(&style_pr,&transition_dsc_pr); //设置样式转换
lv_obj_t * btn1 = lv_btn_create(lv_scr_act()); //创建按键对象
lv_obj_align(btn1,LV_ALIGN_CENTER,0,-80); //居中显示按键对象
lv_obj_add_style(btn1,&style_pr,LV_STATE_PRESSED); //添加样式风格
lv_obj_add_style(btn1,&style_def,0); //添加样式风格
lv_obj_t * label = lv_label_create(btn1); //创建Label
lv_label_set_text(label,"Gum"); //设置Label字内容
}