【LVGL控件学习】圆弧(lv_arc)

本文详细介绍了LVGL库中的lv_arc组件,包括圆弧的颜色设置、手柄去除、值和范围控制、旋转、模式设定、变化率调整、事件响应以及API方法。通过实例演示了如何创建、配置和使用弧形控件进行动画效果的实现。
摘要由CSDN通过智能技术生成

【LVGL控件学习】圆弧(lv_arc)

一、零件和样式

  • LV_PART_MAIN - 背景弧
  • LV_PART_INDICATOR - 前景弧
  • LV_PART_KNOB - 手柄

1. 为圆弧不同部分添加颜色

/**
 * 为圆弧添加颜色时,要使用arc_color而不是bg_color
 * 为手柄添加颜色使用bg_color
 */
lv_obj_set_style_arc_color(arc, lv_color_hex3(0xddc), LV_PART_MAIN);
lv_obj_set_style_arc_color(arc, lv_color_hex3(0xff0), LV_PART_INDICATOR);
lv_obj_set_style_bg_color(arc, lv_color_hex3(0xf60), LV_PART_KNOB);

在这里插入图片描述

2. 移除圆弧的手柄

lv_obj_remove_style(arc, NULL, LV_PART_KNOB);

在这里插入图片描述

二、用法

1. 值和范围

lv_arc_set_range(arc, min, max) - 设置圆弧的范围,默认为1-100

lv_arc_set_value(arc, new_value) - 设置圆弧的值

在这里插入图片描述

lv_obj_t* arc = lv_arc_create(lv_scr_act());
lv_obj_center(arc);
lv_arc_set_range(arc, 0, 100); // 设置圆弧的范围
lv_arc_set_value(arc, 20);     // 设置圆弧的值

int val = 20;        // 弧当前的值
bool forward = true; // 向前标志位
while (!lv_win32_quit_signal)
{
	/* 让弧在20-80之间循环移动 */
    lv_arc_set_value(arc, val); // 设置圆弧的值为val
    if (forward) {
        val++;
    } else {
        val--;
    }

    if (val == 80 || val == 20) { // 当值为20或80移动反向
        forward = !forward;
    }

    Sleep(5); // 延时5ms
}

2. 旋转

设置前景弧的角度

lv_arc_set_start_angle(arc, start_angle, end_angle) - 设置前景弧开始的角度

lv_arc_set_end_angle(arc, start_angle, end_angle) - 设置前景弧结束的角度

lv_arc_set_angles(arc, start_angle, end_angle) - 同时设置前景弧开始和结束的角度

设置背景弧的角度

lv_arc_set_bg_start_angle(arc, start_angle, end_angle) - 设置背景弧开始的角度

lv_arc_set_bg_end_angle(arc, start_angle, end_angle) - 设置背景弧结束的角度

lv_arc_set_bg_angles(arc, start_angle, end_angle) - 同时设置背景弧开始和结束的角度

零度位于对象的中间右侧(3 点钟方向),并且度数沿顺时针方向增加。 角度应在 [0;360] 范围内

即0为最右侧,90为下侧,180为左侧,270为上侧,360为右侧终点

前景弧和背景弧需要同时设置且值一致,否则将会出现显示异常!

在这里插入图片描述

lv_arc_set_angles(arc, 90, 360);    // 设置前景弧角度
lv_arc_set_bg_angles(arc, 90, 360); // 设置背景弧角度
设置0度偏移量(设置起点位置)

lv_arc_set_rotation(arc, deg) - 设置起点的偏移量

偏移量的取值为正数,若为负数可能将造成显示异常

在这里插入图片描述

lv_arc_set_rotation(arc, 90); // 设置起点偏移量 -> 顺时针旋转90度

3. 模式

  • LV_ARC_MODE_NORMAL - 指标弧从最小值绘制到当前值。
  • LV_ARC_MODE_REVERSE -指标弧从最大值到当前值逆时针绘制。
  • LV_ARC_MODE_SYMMETRICAL -指标弧从中间点绘制到当前值。

模式可以通过lv_arc_set_mode(arc, LV_ARC_MODE_...)设置

当模式为LV_ARC_MODE_REVERSE时,请使用lv_arc_set_value(arc, value)来设置圆弧的值,若用触摸设置,可能会出现显示异常。

可使用lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE)禁用弧的点击事件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 变化率

lv_arc_set_change_rage(arc, rate) - 设置圆弧的变化速度,单位 度/秒, 默认720度/秒

在这里插入图片描述
在这里插入图片描述

lv_arc_t * pArc = (lv_arc_t*)arc;					   // 将lv_obj_t*转型为lv_arc_t*
printf("弧默认的速度: %u 度/秒\n", pArc->chg_rate);      // 弧默认的速度: 720 度/秒
lv_arc_set_change_rate(arc, 100);					   // 改变弧的变化速度为100度/秒
printf("弧改变后的速度速度: %u 度/秒\n", pArc->chg_rate); // 弧改变后的速度速度: 100 度/秒

5. 手动设置

要使圆弧不可调整,请使对象不可点击:

lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE); // 使圆弧不可点击

三、事件

LV_EVENT_VALUE_CHANGED - 按下圆弧或者拖动手柄改变圆弧的值

使用lv_arc_change_value(arc, value)不会触发该事件

在这里插入图片描述

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 lv_arc(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;
}

四、示例

请添加图片描述


// 屏幕大小 580 * 250
/**
 * @brief 动画回调函数
 * @param obj 动画处理的对象
 * @param v   当前的值
 */
static void _set_angle(void* obj, int32_t v)
{
    lv_arc_set_value((lv_obj_t*)obj, v); // 设置圆弧的值
}

/**
 * @brief 动画调整圆弧的值
 * @param obj 动画要处理的对象
 * @param val 要改变到的值
 */
static void _set_var_value_anim(lv_obj_t* obj, int val)
{
    lv_anim_t a; 							// 创建动画
    lv_anim_init(&a); 						// 初始化动画
    lv_anim_set_exec_cb(&a, _set_angle); 	// 设置动画回调函数
    uint16_t old = lv_arc_get_value(obj); 	// 获取圆弧当前值
    lv_anim_set_var(&a, obj);             	// 将圆弧与动画绑定
    lv_anim_set_values(&a, old, val);     	// 设置动画处理值的改变范围
    lv_anim_set_time(&a, 1000); 			// 设置动画持续时间
    lv_anim_start(&a); 						// 开始执行动画
}

void arc_demo(void)
{
    /* 屏幕 */
	lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);             // 禁止屏幕滚动
    lv_obj_set_style_text_font(lv_scr_act(), &lv_font_montserrat_30, 0); // 设置文本字体
    lv_obj_set_style_text_align(lv_scr_act(), LV_TEXT_ALIGN_CENTER, 0);  // 设置文本居中对齐
    lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex3(0xffe), 0);    // 设置背景颜色

    /* 温度标签 */
    lv_obj_t* t_label = lv_label_create(lv_scr_act()); // 创建温度标签
    lv_obj_set_size(t_label, 400, 30);                 // 设置标签大小
    lv_obj_align(t_label, LV_ALIGN_CENTER, -100, -30); // 设置标签位置
    lv_label_set_text(t_label, "Temperatur: 26");      // 设置标签内容

    /* 湿度标签 方法同上 */
    lv_obj_t* h_label = lv_label_create(lv_scr_act()); 				   
    lv_obj_set_size(h_label, 400, 30); 								   
    lv_obj_align_to(h_label, t_label, LV_ALIGN_OUT_BOTTOM_MID, 0, 20); 
    lv_label_set_text(h_label, "Humidity: 52"); 					 

    /* 温度弧 */
    lv_obj_t* h_arc = lv_arc_create(lv_scr_act());  // 创建湿度圆弧
    lv_obj_remove_style(h_arc, NULL, LV_PART_KNOB); // 移除圆弧手柄
    lv_obj_add_flag(h_arc, LV_OBJ_FLAG_CLICKABLE);  // 禁止点击事件
    lv_obj_set_size(h_arc, 400, 400);               // 设置圆弧大小
    lv_arc_set_angles(h_arc, 180, 270); 			// 设置前景弧角度
    lv_arc_set_bg_angles(h_arc, 180, 270); 			// 设置背景弧角度
    lv_obj_set_pos(h_arc, 580 - 400 / 2, 250 - 400 / 2); 	  // 设置圆弧位置
    lv_obj_set_style_arc_width(h_arc, 50, LV_PART_INDICATOR); // 设置前景弧宽度
    lv_obj_set_style_arc_width(h_arc, 50, LV_PART_MAIN);      // 设置背景弧宽度
    lv_obj_set_style_arc_color(h_arc, lv_color_hex3(0xf60), LV_PART_INDICATOR); // 设置前景弧颜色
    lv_obj_set_style_arc_color(h_arc, lv_color_hex3(0xfed), LV_PART_MAIN); 	    // 设置背景弧颜色
    lv_obj_set_style_arc_rounded(h_arc, false, LV_PART_MAIN); 					// 取消背景弧圆角
    lv_arc_set_range(h_arc, 0, 100); // 设置圆弧范围
    lv_arc_set_value(h_arc, 52); 	 // 设置圆弧当前值

	/* 湿度弧 方法同上 */
    lv_obj_t* t_arc = lv_arc_create(lv_scr_act());
    lv_obj_remove_style(t_arc, NULL, LV_PART_KNOB);
    lv_obj_add_flag(t_arc, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_set_size(t_arc, 500, 500);
    lv_arc_set_angles(t_arc, 180, 270);
    lv_arc_set_bg_angles(t_arc, 180, 270);
    lv_obj_set_pos(t_arc, 580 - 500 / 2, 250 - 500 / 2);
    lv_obj_set_style_arc_width(t_arc, 50, LV_PART_INDICATOR);
    lv_obj_set_style_arc_width(t_arc, 50, LV_PART_MAIN);
    lv_obj_set_style_arc_color(t_arc, lv_color_hex3(0x09f), LV_PART_INDICATOR);
    lv_obj_set_style_arc_color(t_arc, lv_color_hex3(0xdef), LV_PART_MAIN);
    lv_obj_set_style_arc_rounded(t_arc, false, LV_PART_MAIN);
    // lv_arc_set_range(t_arc, -30, 50); /* !!! 如果范围为负数,执行动画时可能会造成显示异常,故改为正数范围 */
    // lv_arc_set_value(t_arc, 26);
    lv_arc_set_range(t_arc, 0, 80);
    lv_arc_set_value(t_arc, 26 + 30);
    
    int time = 0;   // 时间标记
    int temp, humi; // 温湿度值
    while (!lv_win32_quit_signal)
    {
        if (time >= 200) // 延时时间
        {
            time = 0;    // 时间标记复位
            temp = rand() % 70 + 6 ;          // 简单随机数获取温湿度值
            humi = rand() % 80 + 11;
            _set_var_value_anim(t_arc, temp); // 动画设置圆弧的值
            _set_var_value_anim(h_arc, humi);
            lv_label_set_text_fmt(t_label, "Temperatur: %d", temp - 30); // 改变标签文本
            lv_label_set_text_fmt(h_label, "Humidity: %d", humi);
        }
        
        time++;			   // 时间标记自增
        lv_task_handler(); // lvgl任务处理函数
        Sleep(1);          // 延时函数
    }
    
    return;
}

五、API

1. 类型定义

// 弧的模式
typedef uint8_t lv_arc_mode_t

2. 枚举

enum {
    LV_ARC_MODE_NORMAL,      // 指标弧从最小值绘制到当前值
    LV_ARC_MODE_SYMMETRICAL, // 指标弧从最大值到当前值逆时针绘制
    LV_ARC_MODE_REVERSE      // 指标弧从中间点绘制到当前值
};

3. 方法

/**
 * @brief 创建一个弧
 * @param parent 指向对象的指针,它将是新圆弧的父对象
 * @return 指向创建的圆弧的指针
*/
lv_obj_t *lv_arc_create(lv_obj_t *parent);


/**
 * @brief 设置圆弧的起始角度。0度: 右侧; 90度: 底部...
 * @param arc   指向要设置的圆弧的指针
 * @param start 起始角度
*/
void lv_arc_set_start_angle(lv_obj_t *arc, uint16_t start);


/**
 * @brief 设置圆弧的结束角度。0度: 右侧; 90度: 底部...
 * @param arc 指向要设置的圆弧的指针
 * @param end 结束角度
*/
void lv_arc_set_end_angle(lv_obj_t *arc, uint16_t end);


/**
 * @brief 设置圆弧的开始角度和结束角度
 * @param arc   指向要设置的圆弧的指针
 * @param start 开始角度
 * @param end   结束角度
*/
void lv_arc_set_angles(lv_obj_t *arc, uint16_t start, uint16_t end);


/**
 * @brief 设置弧形背景的起始角度
 * @param arc   指向要设置的圆弧的指针
 * @param start 起始角度
*/
void lv_arc_set_bg_start_angle(lv_obj_t *arc, uint16_t start);


/**
 * @brief 设置弧形背景的结束角度
 * @param arc 指向要设置的圆弧的指针
 * @param end 结束角度
*/
void lv_arc_set_bg_end_angle(lv_obj_t *arc, uint16_t end);


/**
 * @brief 设置弧形背景的起始角度和结束角度
 * @param arc   指向要设置的圆弧的指针
 * @param start 起始角度
 * @param end   结束角度
*/
void lv_arc_set_bg_angles(lv_obj_t *arc, uint16_t start, uint16_t end);


/**
 * @brief 设置整个圆弧的旋转
 * @param arc      指向要设置的圆弧的指针
 * @param rotation 旋转角度
*/
void lv_arc_set_rotation(lv_obj_t *arc, uint16_t rotation);


/**
 * @brief 设置圆弧的类型
 * @param arc  指向要设置的圆弧的指针
 * @param type 圆弧类型
*/
void lv_arc_set_mode(lv_obj_t *arc, lv_arc_mode_t type);


/**
 * @brief 设置圆弧的值
 * @param arc  指向要设置的圆弧的指针
 * @param value 圆弧的值
*/
void lv_arc_set_value(lv_obj_t *arc, int16_t value);


/**
 * @brief 设置圆弧的范围
 * @param arc 指向要设置的圆弧的指针
 * @param min 最小值
 * @param max 最大值
*/
void lv_arc_set_range(lv_obj_t *arc, int16_t min, int16_t max);


/**
 * @brief 设置一个变化率来限制电弧到达按压点的速度。
 * @param arc 指向目标圆弧的指针
 * @param rate 变化率
*/
void lv_arc_set_change_rate(lv_obj_t *arc, uint16_t rate);


/**
 * @brief 获取圆弧的起始角度。
 * @param arc 指向目标圆弧的指针
 * @return 起始角度 [0, 360]
*/
uint16_t lv_arc_get_angle_start(lv_obj_t *obj);


/**
 * @brief 获取圆弧的结束角度。
 * @param arc 指向圆弧的指针
 * @return 结束角度 [0, 360]
*/
uint16_t lv_arc_get_angle_end(lv_obj_t *obj);


/**
 * @brief 获取弧形背景的起始角度
 * @param arc 指向圆弧的指针
 * @return 角度 [0, 360]
*/
uint16_t lv_arc_get_bg_angle_start(lv_obj_t *obj);


/**
 * @brief 获取弧形背景的结束角度
 * @param arc 指向圆弧的指针
 * @return 角度 [0, 360]
*/
uint16_t lv_arc_get_bg_angle_end(lv_obj_t *obj)


/**
 * @brief 获取圆弧的值
 * @param arc 指向圆弧的指针
 * @return 圆弧的值
*/
int16_t lv_arc_get_value(const lv_obj_t *obj);


/**
 * @brief 获取圆弧的最小值
 * @param arc 指向圆弧的指针
 * @return 圆弧的最小值
*/
int16_t lv_arc_get_min_value(const lv_obj_t *obj);


/**
 * @brief 获取圆弧的最大值
 * @param arc 指向圆弧的指针
 * @return 圆弧的最大值
*/
int16_t lv_arc_get_max_value(const lv_obj_t *obj);


/**
 * @brief 获取圆弧的模式
 * @param arc 指向圆弧的指针
 * @return 圆弧的模式
*/
lv_arc_mode_t lv_arc_get_mode(const lv_obj_t *obj);
  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lv_arc_set_bg_angles函数是用来设置Arc控件的背景角度的。通过该函数可以指定Arc控件的背景起始角度和结束角度。\[1\]例如,可以使用lv_arc_set_bg_angles(arc, start_angle, end_angle)来设置Arc控件的背景角度范围。其中,arcArc控件的指针,start_angle是背景起始角度,end_angle是背景结束角度。\[1\] 下面是一个使用lv_arc_set_bg_angles函数的示例代码: ```c void lvgl_arc_angle_test(void) { /* 创建一个Arc控件 */ lv_obj_t* arc = lv_arc_create(lv_scr_act(), NULL); /* 设置背景角度范围 */ lv_arc_set_bg_angles(arc, 180, 360); /* 设置Arc控件的角度范围 */ lv_arc_set_angles(arc, 180, 270); /* 设置Arc控件的大小 */ lv_obj_set_size(arc, 200, 200); /* 将Arc控件居中对齐 */ lv_obj_align(arc, NULL, LV_ALIGN_CENTER, 0, 0); } ``` 在上述示例代码中,我们创建了一个Arc控件,并使用lv_arc_set_bg_angles函数设置了背景角度范围为180度到360度。\[2\]这样,Arc控件的背景将会从180度开始绘制,一直绘制到360度。 #### 引用[.reference_title] - *1* *2* *3* [用GUI画个弧?走起!LVGLArc控件』介绍走起](https://blog.csdn.net/XiaoXiaoPengBo/article/details/113869980)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值