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);
    }
}
posted @ 2024-05-07 20:44  星光映梦  阅读(27)  评论(0编辑  收藏  举报