目录
- 一、圆弧部件
- 1、部件组成
- 2、lv_art_t
- 3、圆弧部件角度设置
- 4、圆弧部件旋转设置
- 5、圆弧的模式选择
- 6、圆弧部件的变化率设置
- 7、移除旋钮
- 8、事件
- 9、获取/设置信息相关的 API
- 二、例程
一、圆弧部件
1、部件组成
圆弧(lv_arc)部件由三个部分组成:背景弧、前景弧和旋钮,示意图如下:
各组成部分的相关枚举和作用如下所示:
- 背景弧(LV_PART_MAIN):用于显示范围值;
- 前景弧(LV_PART_INDICATOR):用于显示当前值;
- 旋钮(LV_PART_KNOB):用于调节当前值。
2、lv_art_t
该结构体定义在 lvgl\src\widgets\arc\lv_arc.h
目录下:
typedef struct {
lv_obj_t obj; // 基础对象
int32_t rotation; // 旋转度
lv_value_precise_t indic_angle_start; // 前景弧起始角度
lv_value_precise_t indic_angle_end; // 前景弧终止角度
lv_value_precise_t bg_angle_start; // 背景弧起始角度
lv_value_precise_t bg_angle_end; // 背景弧终止角度
int32_t value; /* 当前圆弧值 */
int32_t min_value; /* 最小圆弧值 */
int32_t max_value; /* 最大圆弧值 */
uint32_t dragging : 1;
uint32_t type : 2;
uint32_t min_close : 1; /*1: the last pressed angle was closer to minimum end*/
uint32_t in_out : 1; /* 1: The click was within the background arc angles. 0: Click outside */
uint32_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/
uint32_t last_tick; /*Last dragging event timestamp of the arc*/
lv_value_precise_t last_angle; /*Last dragging angle of the arc*/
int16_t knob_offset; /*knob offset from the main arc*/
} lv_arc_t;
其中,value
指的是当前前景弧所指示的值,而 min_value
和 max_value
指定了圆弧当前值的可变化范围。如下例:
void my_gui(void)
{
lv_obj_t* arc = lv_arc_create(lv_scr_act());
lv_arc_set_range(arc, 0, 100); /* 设置arc 的范围 */
lv_arc_set_value(arc, 50); /* 设置arc 的值 */
lv_obj_set_size(arc, 200, 200);
lv_obj_align_to(arc, NULL, LV_ALIGN_CENTER, 0, 0);
}
结果如下:
3、圆弧部件角度设置
在圆弧部件默认的角度划分中,0 度(绝对度数)位于对象右侧中部(3 点钟方向),然后沿顺时针方向增加度数,直至 360 度,示意图如下:
下面是和圆弧角度设置的相关函数,分别为背景弧角度设置和前景弧角度设置:
- 背景弧角度设置
函数 | 含义 |
---|---|
lv_arc_set_bg_angles(arc, start_angle, end_angle) | 同时设置起始角度和终止角度 |
lv_arc_set_bg_start/end_angle(arc, start_angle) | 单独设置起始角度/终止角度 |
- 前景弧角度设置
函数 | 含义 |
---|---|
lv_arc_set_angles(arc, start_angle, end_angle) | 同时设置起始角度和终止角度 |
lv_arc_set_start/end_angle(arc, start_angle) | 单独设置起始角度/终止角度 |
注意:前景弧的角度范围不能超过背景弧的角度范围,否则将会出现显示异常,该异常会在下次更新布局时被修正。
例如:
void my_gui(void)
{
lv_obj_t* arc = lv_arc_create(lv_scr_act());
lv_arc_set_angles(arc, 270, 360); // 设置前景弧角度
lv_arc_set_bg_angles(arc, 270, 360); // 设置背景弧角度
lv_obj_set_size(arc, 200, 200);
lv_obj_align_to(arc, NULL, LV_ALIGN_CENTER, 0, 0);
}
前景弧和背景弧需要同时设置且值一致,否则将会出现显示异常!
4、圆弧部件旋转设置
圆弧部件旋转是指将整个部件沿顺时针方向旋转某个角度,注意:旋转的角度为相对值(增量),它的范围是 0~360
度,旋转中心为圆弧的中心。圆弧旋转的示意图如下(旋转 180 度):
注意:圆弧旋转后,它的角度划分(绝对度数)就会发生变化。
函数 | 含义 |
---|---|
lv_arc_set_rotation(arc, deg) | 设置起点的偏移量 |
偏移量的取值为正数,若为负数可能将造成显示异常
例:
void my_gui(void)
{
lv_obj_t* arc = lv_arc_create(lv_scr_act());
lv_arc_set_bg_angles(arc, 135, 45); // 设置背景弧的起始角度和终止角度
lv_arc_set_angles(arc, 135, 300); // 设置前景弧的起始角度和终止角度
lv_arc_set_rotation(arc, 180); // 旋转180 度
lv_obj_set_size(arc, 200, 200);
lv_obj_align_to(arc, NULL, LV_ALIGN_CENTER, 0, 0);
}
可以看到,圆弧旋转了 180 度。
5、圆弧的模式选择
默认情况下,圆弧部件是沿顺时针方向绘制的,如果用户需要修改绘制的方向,可以调用 lv_arc_set_mode
函数,设置圆弧的绘制模式,圆弧模式相关的枚举如下所示:
LV_ARC_MODE_NORMAL
:顺时针方向绘制;- ·
LV_ARC_MODE_REVERSE
:逆时针方向绘制; LV_ARC_MODE_SYMMETRICAL
:从中间点开始绘制到当前值。
当模式为
LV_ARC_MODE_REVERSE
时,请使用lv_arc_set_value(arc, value)
来设置圆弧的值,若用触摸设置,可能会出现显示异常。
可使用lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE)
禁用弧的点击事件
逆时针设置:
从中间开始绘制:
6、圆弧部件的变化率设置
当圆弧的旋钮被滑动时,前景弧将根据设定的变化率来绘制。变化率的单位为:度/秒。默认 720 度/秒。
函数 | 含义 |
---|---|
lv_arc_set_change_rage | 设置变化率 |
7、移除旋钮
当我们将圆弧作为进度指示器或者参数指示器来使用时,则需要移除它的旋钮,并清除可点击的属性,示例代码如下:
lv_obj_t *arc = lv_arc_create(lv_scr_act());
lv_obj_remove_style(arc, NULL, LV_PART_KNOB); /* 移除旋钮 */
lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE); /* 清除可点击属性 */
lv_obj_center(arc);
8、事件
LV_EVENT_VALUE_CHANGED
:按下圆弧或者拖动按钮改变圆弧的值;LV_ARC_DRAW_PART_BACKGROUND
:绘制背景弧线;LV_ARC_DRAW_PART_FOREGROUND
:绘制前景弧线;LV_ARC_DRAW_PART_KNOB
:绘制旋钮。
例:当我们拖动按钮或圆弧时,中间的数值也会实时变化。
static void _arc_cb(lv_event_t* e)
{
lv_obj_t* label = (lv_obj_t*)lv_event_get_user_data(e); // 获取传进来的用户数据label
lv_obj_t* arc = lv_event_get_target(e); // 获取触发的控件arc
uint16_t value = lv_arc_get_value(arc); // 获取arc当前的值
lv_label_set_text_fmt(label, "Value: %u", value); // 更新label的显示
return;
}
void my_gui(void)
{
lv_obj_t* label = lv_label_create(lv_scr_act()); // 创建用于显示当前弧的值的标签
lv_obj_center(label);
lv_label_set_text(label, "Value: 0");
lv_obj_t* arc = lv_arc_create(lv_scr_act()); // 创建圆弧
lv_obj_add_event_cb(arc, _arc_cb, LV_EVENT_VALUE_CHANGED, (void*)label); // 添加回调函数
lv_obj_center(arc);
lv_arc_set_value(arc, 0); // 设置当前值
lv_arc_set_range(arc, 0, 100); // 设置弧的范围
lv_arc_set_change_rate(arc, 200); // 设置弧的速度
return;
}
9、获取/设置信息相关的 API
函数 | 含义 |
---|---|
lv_arc_create() | 创建圆弧对象 |
lv_arc_set_start_angle() | 设置前景弧的起始角度 |
lv_arc_set_end_angle() | 设置前景弧的结束角度 |
lv_arc_set_angles() | 设置前景弧的开始和结束角度 |
lv_arc_set_bg_start_angle() | 设置背景弧的起始角度 |
lv_arc_set_bg_end_angle() | 设置背景弧的结束角度 |
lv_arc_set_bg_angles() | 设置背景弧的起止和结束角度 |
lv_arc_set_rotation() | 设置圆弧的旋转 |
lv_arc_set_mode() | 设置圆弧的模式 |
lv_arc_set_value() | 设置圆弧当前值 |
lv_arc_set_range() | 设置圆弧范围 |
lv_arc_set_change_rate() | 设置变化率 |
lv_arc_get_angle_start() | 获取前景弧的起始角度 |
lv_arc_get_angle_end() | 获取前景弧的结束角度 |
lv_arc_get_bg_angle_start() | 获取背景弧的起始角度 |
lv_arc_get_bg_angle_end() | 获取背景弧的结束角度 |
lv_arc_get_value() | 获取圆弧的当前值 |
lv_arc_get_min_value() | 获取圆弧的最小值 |
lv_arc_get_max_value() | 获取圆弧的最大值 |
lv_arc_get_mode() | 获取圆弧的模式 |
二、例程
static void arc_event_cb(lv_event_t * e)
{
lv_obj_t * arc = lv_event_get_target(e);
lv_obj_t * label = lv_event_get_user_data(e);
lv_label_set_text_fmt(label, "%d", lv_arc_get_value(arc));
}
static void set_arc_value(void * obj, int32_t v)
{
lv_arc_set_value(obj, v);
// 通知arc和label数值已被改变
lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
}
void my_gui(void)
{
/*Create an Arc*/
lv_obj_t * arc = lv_arc_create(lv_scr_act());
lv_arc_set_rotation(arc, 270);
lv_arc_set_bg_angles(arc, 0, 360);
lv_obj_remove_style(arc, NULL, LV_PART_KNOB); /*Be sure the knob is not displayed*/
lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE); /*To not allow adjusting by click*/
lv_obj_center(arc);
// 动画相关后面会提到
/********************************************************/
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, arc);
lv_anim_set_exec_cb(&a, set_arc_value);
lv_anim_set_time(&a, 1000);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); /*无限重复*/
lv_anim_set_repeat_delay(&a, 500);
lv_anim_set_values(&a, 0, 100);
lv_anim_start(&a);
/********************************************************/
// 创建label展示arc数值
lv_obj_t * label = lv_label_create(arc);
lv_obj_center(label);
lv_obj_add_event_cb(arc, arc_event_cb, LV_EVENT_VALUE_CHANGED, label); // 添加回调事件
}