请教一下各位大佬lvgl要怎么才能画出这种方形的进度条

image
就是图片中的这种进度条


void update_progress_bar(lv_obj_t* canvas, int progress) {
    // 轨道参数
    int track_width = 20;    // 轨道宽度
    int arc_radius = 40;     // 圆角半径
    int canvas_width = 200;  // 画布宽度
    int canvas_height = 400; // 画布高度

    // 绘制样式
    lv_draw_rect_dsc_t draw_dsc;
    lv_draw_rect_dsc_init(&draw_dsc);
    draw_dsc.bg_color = lv_color_make(255, 165, 0);  // 轨道颜色(橙色)
    draw_dsc.border_width = 0;

    lv_draw_arc_dsc_t arc_dsc;
    lv_draw_arc_dsc_init(&arc_dsc);
    arc_dsc.width = track_width;
    arc_dsc.color = lv_color_make(255, 165, 0); // 弧线颜色

    // 圆弧位置
    int left = arc_radius;                     // 左边界
    int right = canvas_width - arc_radius;     // 右边界
    int top = arc_radius;                      // 上边界
    int bottom = canvas_height - arc_radius;   // 下边界

    // 清空画布
    lv_canvas_fill_bg(canvas, lv_color_black(), LV_OPA_COVER);

    // 总轨道长度 = 2 * 水平长度 + 2 * 垂直长度 + 4 * 圆弧长度
    int arc_length = arc_radius * 3.1415 / 2; // 单个圆弧长度(1/4圆周长)
    int total_length = (right - left) * 2 + (bottom - top) * 2 + 4 * arc_length;
    int draw_length = (progress * total_length) / 100; // 当前需要绘制的长度

    // 1. 上水平矩形
    if (draw_length > 0) {
        int seg_length = right - left; // 水平矩形长度
        int to_draw = LV_MIN(draw_length, seg_length);
        lv_canvas_draw_rect(canvas, left, 0, to_draw, track_width, &draw_dsc);
        draw_length -= to_draw;
    }

    // 2. 右上圆弧
    if (draw_length > 0) {
        int arc_seg_length = arc_length; // 圆弧的实际长度
        int to_draw = LV_MIN(draw_length, arc_seg_length);
        int angle_end = 270 + (to_draw * 90 / arc_seg_length); // 计算角度
        lv_canvas_draw_arc(canvas, right, top, arc_radius, 270, angle_end, &arc_dsc);
        draw_length -= to_draw;
    }

    // 3. 右垂直矩形
    if (draw_length > 0) {
        int seg_length = bottom - top; // 垂直矩形长度
        int to_draw = LV_MIN(draw_length, seg_length);
        lv_canvas_draw_rect(canvas, canvas_width - track_width, top, track_width, to_draw, &draw_dsc);
        draw_length -= to_draw;
    }

    // 4. 右下圆弧
    if (draw_length > 0) {
        int arc_seg_length = arc_length; // 圆弧的实际长度
        int to_draw = LV_MIN(draw_length, arc_seg_length);
        int angle_end = 0 + (to_draw * 90 / arc_seg_length); // 计算角度
        lv_canvas_draw_arc(canvas, right, bottom, arc_radius, 0, angle_end, &arc_dsc);
        draw_length -= to_draw;
    }

    // 5. 下水平矩形
    if (draw_length > 0) {
        int seg_length = right - left; // 水平矩形长度
        int to_draw = LV_MIN(draw_length, seg_length);
        lv_canvas_draw_rect(canvas, right - to_draw, canvas_height - track_width, to_draw, track_width, &draw_dsc);
        draw_length -= to_draw;
    }



    // 6. 左下圆弧
    if (draw_length > 0) {
        int arc_seg_length = arc_length; // 圆弧的实际长度
        int to_draw = LV_MIN(draw_length, arc_seg_length);
        int angle_end = 90 + (to_draw * 90 / arc_seg_length); // 计算角度
        lv_canvas_draw_arc(canvas, left, bottom, arc_radius, 90, angle_end, &arc_dsc);
        draw_length -= to_draw;
    }

    // 7. 左垂直矩形
    if (draw_length > 0) {
        int seg_length = bottom - top; // 垂直矩形长度
        int to_draw = LV_MIN(draw_length, seg_length);
        lv_canvas_draw_rect(canvas, 0, top + (seg_length - to_draw), track_width, to_draw, &draw_dsc);
        draw_length -= to_draw;
    }

    // 8. 左上圆弧
    if (draw_length > 0) {
        int arc_seg_length = arc_length; // 圆弧的实际长度
        int to_draw = LV_MIN(draw_length, arc_seg_length);
        int angle_end = 180 + (to_draw * 90 / arc_seg_length); // 计算角度
        lv_canvas_draw_arc(canvas, left, top, arc_radius, 180, angle_end, &arc_dsc);
        draw_length -= to_draw;
    }
}


static void my_timer(lv_timer_t* timer)
{
    static int i = 0;
    lv_obj_t* canvas = (lv_obj_t*)timer->user_data;
    if (i <= 99)i++;
    update_progress_bar(canvas, i);
}

int app_canvas_2(lv_obj_t *parent)
{
    lv_obj_t* canvas = lv_canvas_create(parent);
    lv_obj_set_size(canvas, 200, 400);  // 设置画布大小:宽200,高400
    lv_obj_center(canvas);

    // 定义画布缓冲区
    static lv_color_t cbuf[200 * 400];
    lv_canvas_set_buffer(canvas, cbuf, 200, 400, LV_IMG_CF_TRUE_COLOR);

    // 清空画布背景
    lv_canvas_fill_bg(canvas, lv_color_black(), LV_OPA_COVER);

    // 轨道参数
    int track_width = 20;    // 轨道宽度
    int arc_radius = 40;     // 圆角半径
    int canvas_width = 200;  // 画布宽度
    int canvas_height = 400; // 画布高度

    // 绘制样式
    lv_draw_rect_dsc_t draw_dsc;
    lv_draw_rect_dsc_init(&draw_dsc);
    draw_dsc.bg_color = lv_color_make(255, 165, 0);  // 轨道颜色(橙色)
    draw_dsc.border_width = 0;

    // 圆弧样式
    lv_draw_arc_dsc_t arc_dsc;
    lv_draw_arc_dsc_init(&arc_dsc);
    arc_dsc.width = track_width;
    arc_dsc.color = lv_color_make(255, 165, 0); // 弧线颜色

    // 圆弧位置
    int left = arc_radius;                     // 左边界
    int right = canvas_width - arc_radius;     // 右边界
    int top = arc_radius;                      // 上边界
    int bottom = canvas_height - arc_radius;   // 下边界

    // 1. 绘制4个圆弧
    lv_canvas_draw_arc(canvas, left, top, arc_radius, 180, 270, &arc_dsc);   // 左上
    lv_canvas_draw_arc(canvas, left, bottom, arc_radius, 90, 180, &arc_dsc); // 左下
    lv_canvas_draw_arc(canvas, right, top, arc_radius, 270, 360, &arc_dsc);  // 右上
    lv_canvas_draw_arc(canvas, right, bottom, arc_radius, 0, 90, &arc_dsc);  // 右下

    // 2. 绘制4段矩形
    // 上水平矩形
    lv_canvas_draw_rect(canvas, left, 0, right - left, track_width, &draw_dsc);
    // 下水平矩形
    lv_canvas_draw_rect(canvas, left, canvas_height - arc_dsc.width, right - left, track_width, &draw_dsc);
    // 左垂直矩形
    lv_canvas_draw_rect(canvas, 0, top, track_width, bottom - top, &draw_dsc);
    // 右垂直矩形
    lv_canvas_draw_rect(canvas, canvas_width - arc_dsc.width, top, track_width, bottom - top, &draw_dsc);
    
    lv_timer_create(my_timer, 300, canvas);

    return 0;
}

1 个赞

感谢大佬,我去试试 :+1: :+1: :+1: :+1: :+1: