06. 圆弧部件
一、圆弧部件
圆弧部件以弧形的形式来调节、显示某个参数的值。圆弧(lv_arc)部件由三个部分组成:背景弧(LV_PART_MAIN
)、前景弧(LV_PART_INDICATOR
)和 旋钮(LV_PART_KNOB
),示意图如下:
LVGL 官方提供了一些与圆弧部件相关 API 函数。
lv_obj_t * lv_arc_create(lv_obj_t * parent); // 创建圆弧对象
void lv_arc_set_start_angle(lv_obj_t * obj, lv_value_precise_t start); // 设置前景弧的起始角度
lv_value_precise_t lv_arc_get_angle_start(lv_obj_t * obj); // 获取前景弧的起始角度
void lv_arc_set_end_angle(lv_obj_t * obj, lv_value_precise_t end); // 设置前景弧的结束角度
lv_value_precise_t lv_arc_get_angle_end(lv_obj_t * obj); // 获取前景弧的结束角度
void lv_arc_set_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_precise_t end); // 设置前景弧的开始和结束角度
void lv_arc_set_bg_start_angle(lv_obj_t * obj, lv_value_precise_t start); // 设置背景弧的起始角度
lv_value_precise_t lv_arc_get_bg_angle_start(lv_obj_t * obj); // 获取背景弧的起始角度
void lv_arc_set_bg_end_angle(lv_obj_t * obj, lv_value_precise_t end); // 设置背景弧的结束角度
lv_value_precise_t lv_arc_get_bg_angle_end(lv_obj_t * obj); // 获取背景弧的结束角度
void lv_arc_set_bg_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_precise_t end); // 设置背景弧的起止和结束角度
void lv_arc_set_rotation(lv_obj_t * obj, int32_t rotation); // 设置圆弧的旋转
void lv_arc_set_mode(lv_obj_t * obj, lv_arc_mode_t type); // 设置圆弧的模式
lv_arc_mode_t lv_arc_get_mode(const lv_obj_t * obj); // 获取圆弧的模式
void lv_arc_set_value(lv_obj_t * obj, int32_t value); // 设置圆弧当前值
int32_t lv_arc_get_value(const lv_obj_t * obj); // 获取圆弧的当前值
void lv_arc_set_range(lv_obj_t * obj, int32_t min, int32_t max); // 设置圆弧范围
int32_t lv_arc_get_min_value(const lv_obj_t * obj); // 获取圆弧的最小值
int32_t lv_arc_get_max_value(const lv_obj_t * obj); // 获取圆弧的最大值
void lv_arc_set_change_rate(lv_obj_t * obj, uint32_t rate); // 设置变化率
我们可以使用 lv_arc_create()
函数 创建圆弧对象。
/**
* @brief 创建圆弧对象
*
* @param parent 指向父部件的指针
* @return lv_obj_t* 指向圆弧部件的指针
*/
lv_obj_t * lv_arc_create(lv_obj_t * parent);
圆弧当前值 指的是 当前前景弧所指示的值,范围值 是指 圆弧当前值的可变化范围,示意图如下:
/**
* @brief 设置圆弧范围
*
* @param obj 指向圆弧的指针
* @param min 最小值
* @param max 最大值
*/
void lv_arc_set_range(lv_obj_t * obj, int32_t min, int32_t max);
/**
* @brief 设置圆弧当前值
*
* @param obj 指向圆弧的指针
* @param value 当前值
*/
void lv_arc_set_value(lv_obj_t * obj, int32_t value);
在圆弧部件默认的角度划分中,0 度(绝对度数)位于对象右侧中部(3 点钟方向),然后沿顺时针方向增加度数,直至 360 度,示意图如下:
圆弧角度设置的相关函数,它们可以分为两类:背景弧角度设置 和 前景弧角度设置,具体函数如下所示:
/**
* @brief 设置前景弧的起始角度
*
* @param obj 指向圆弧部件的指针
* @param start 起始角度
*/
void lv_arc_set_start_angle(lv_obj_t * obj, lv_value_precise_t start);
/**
* @brief 设置前景弧的结束角度
*
* @param obj 指向圆弧部件的指针
* @param end 结束角度
*/
void lv_arc_set_end_angle(lv_obj_t * obj, lv_value_precise_t end);
/**
* @brief 设置前景弧的开始和结束角度
*
* @param obj 指向圆弧部件的指针
* @param start 起始角度
* @param end 结束角度
*/
void lv_arc_set_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_precise_t end);
/**
* @brief 设置背景弧的起始角度
*
* @param obj 指向圆弧部件的指针
* @param start 起始角度
*/
void lv_arc_set_bg_start_angle(lv_obj_t * obj, lv_value_precise_t start);
/**
* @brief 设置背景弧的结束角度
*
* @param obj 指向圆弧部件的指针
* @param end 结束角度
*/
void lv_arc_set_bg_end_angle(lv_obj_t * obj, lv_value_precise_t end);
/**
* @brief 设置背景弧的起止和结束角度
*
* @param obj 指向圆弧部件的指针
* @param start 起始角度
* @param end 结束角度
*/
void lv_arc_set_bg_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_precise_t end);
前景弧的角度范围不能超过背景弧的角度范围,否则将会出现显示异常,该异常会在下次更新布局时被修正。
圆弧部件旋转是指将整个部件沿顺时针方向旋转某个角度,旋转的角度为相对值(增量),它的范围是 0 ~ 360 度,旋转中心为圆弧的中心。
圆弧旋转后,它的角度划分(绝对度数)就会发生变化。
默认情况下,圆弧部件是沿顺时针方向绘制的,如果用户需要 修改绘制的方向,可以调用 lv_arc_set_mode()
函数,设置圆弧的绘制模式。
/**
* @brief 设置圆弧的模式
*
* @param obj 指向圆弧部件的指针
* @param type 要设置的模式
*/
void lv_arc_set_mode(lv_obj_t * obj, lv_arc_mode_t type);
圆弧模式相关的枚举如下所示:
enum _lv_arc_mode_t {
LV_ARC_MODE_NORMAL, // 顺时针方向绘制
LV_ARC_MODE_SYMMETRICAL, // 逆时针方向绘制
LV_ARC_MODE_REVERSE // 中间点开始绘制到当前值
};
当圆弧的旋钮被滑动时,前景弧将根据设定的变化率来绘制。变化率的单位为:度/秒,用户可调用 lv_arc_set_change_rage()
函数 设置变化率。
/**
* @brief 设置变化率
*
* @param obj 指向圆弧部件的指针
* @param rate 变化率
*/
void lv_arc_set_change_rate(lv_obj_t * obj, uint32_t rate);
当我们将圆弧作为进度指示器或者参数指示器来使用时,则需要移除它的旋钮,并清除可点击的属性,示例代码如下:
lv_obj_remove_style(arc, NULL, LV_PART_KNOB); // 移除旋钮
lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE); // 清除可点击属性
二、实验例程
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
lv_obj_t *label;
int main(void)
{
HAL_Init();
System_Clock_Init(8, 336, 2, 7);
Delay_Init(168);
SPI_Simulate_Init();
// SRAM_Init();
TIM_Base_Init(&g_tim6_handle, TIM6, 83, 999);
__HAL_TIM_CLEAR_IT(&g_tim6_handle, TIM_IT_UPDATE); // 清除更新中断标志位
HAL_TIM_Base_Start_IT(&g_tim6_handle); // 使能更新中断,并启动计数器
lv_init();
lv_port_disp_init();
lv_port_indev_init();
// 测试代码
label = lv_label_create(lv_scr_act()); // 创建标签部件
lv_obj_set_align(label, LV_ALIGN_TOP_MID); // 设置标签部件考上居中对齐
lv_obj_set_style_text_font(label, &lv_font_montserrat_30, LV_PART_MAIN); // 设置标签部件的字体样式
lv_label_set_text(label, "arc test"); // 设置标签部件的文本
lv_obj_t *arc = lv_arc_create(lv_scr_act()); // 创建圆弧部件
lv_obj_center(arc); // 圆弧部件居中对齐
// 设置前景图角度时推荐先设置背景图角度,如果背景图角度范围小于前景图角度范围,则会出现前景图角度跳变问题
lv_arc_set_bg_angles(arc, 0, 360);
lv_arc_set_angles(arc, 0, 360);
lv_arc_set_rotation(arc, 270); // 圆弧部件旋转270°
lv_arc_set_range(arc, 0, 360); // 设置圆弧范围
lv_arc_set_value(arc, 270); // 设置当前值
lv_arc_set_change_rate(arc, 90); // 设置圆弧变化速率
lv_obj_add_event_cb(arc, arc_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
while (1)
{
lv_timer_handler();
Delay_ms(5);
}
return 0;
}
void arc_event_cb(lv_event_t *e)
{
lv_event_code_t code = lv_event_get_code(e); // 获取事件的触发类型
lv_obj_t *target = lv_event_get_target(e); // 获取事件的触发源
int32_t value = 0;
if(code == LV_EVENT_VALUE_CHANGED)
{
value = lv_arc_get_value(target);
lv_label_set_text_fmt(label, "value %ld", value);
}
}