提问关于LVGL部件样式的旋转问题

本人在LVGL 8.2版本的开发中遇到一个问题,我想把LVGL的一个部件进行90度或者180度旋转,发现LVGL8.2版本居然没有旋转部件的功能,百度也没有人提出关于此问题,请问有什么办法让LVGL 的部件进行旋转么?

【以下回答由 GPT 生成】

LVGL 8.2版本中的部件(widget)旋转功能确实不支持。然而,你可以使用以下方法来实现部件的旋转:

  1. 创建一个容器(container)来包含要旋转的部件。
  2. 设置容器的大小和位置,以使其适应要旋转的部件。
  3. 将要旋转的部件添加到容器中。
  4. 使用LVGL中的画布(canvas)功能或重写部件的绘图函数来绘制要旋转的内容。
  5. 使用LVGL的转换矩阵(transformation matrix)功能来旋转容器。

下面是一个示例代码,展示如何将一个按钮部件旋转90度:

#include "lvgl/lvgl.h"

void draw_rotated_button(lv_obj_t *obj, const lv_area_t *clip_area){
    lv_draw_rect_dsc_t rect_dsc;
    lv_draw_rect_dsc_init(&rect_dsc);
    lv_obj_draw_part_dsc_init(obj, LV_OBJ_PART_MAIN, &rect_dsc);

    const lv_style_t *style = obj->styles[LvObjPart_MAIN];

    lv_area_t btn_area;
    lv_obj_get_coords(obj, &btn_area);

    lv_coord_t width = lv_obj_get_width(obj);
    lv_coord_t height = lv_obj_get_height(obj);
    int16_t new_width = height; // 旋转90度后,宽度变为原来的高度
    int16_t new_height = width; // 旋转90度后,高度变为原来的宽度

    lv_draw_rect(&btn_area, clip_area, &rect_dsc, style->body.opa_scale, false);

    /* 旋转后按钮区域和按钮之间的差距 */
    btn_area.x1 += (width - new_width) / 2;
    btn_area.x2 -= (width - new_width) / 2;
    btn_area.y1 += (height - new_height) / 2;
    btn_area.y2 -= (height - new_height) / 2;

    lv_obj_draw_content(obj, &btn_area, clip_area);

    /* 绘制按钮的文本 */
    const char *text = lv_obj_get_text(obj);
    lv_point_t text_pos;
    lv_txt_get_size(&text_pos, text, style->text.font, style->text.letter_space, style->text.line_space,
                    style->text.flag);

    /* 旋转后文本的位置 */
    text_pos.x = btn_area.x1 + (new_width - text_pos.y) /2;
    text_pos.y = btn_area.y1 + (new_height - text_pos.x) /2;

    lv_draw_label(&text_pos, clip_area, &rect_dsc, style->text.opa_scale, text, NULL, 0, NULL, NULL,
                  false, LV_LABEL_ALIGN_CENTER);

}

void rotate_widget(lv_obj_t *obj, int16_t angle){
    lv_obj_t *parent = lv_obj_get_parent(obj);
    lv_obj_t *container = lv_cont_create(parent, NULL);
    lv_cont_set_fit(container, LV_FIT_TIGHT);
    lv_disp_layout_set(lv_obj_get_disp(parent), container, LV_LAYOUT_ROW_M);
    lv_obj_set_auto_realign(container, true);
    lv_obj_align_origo(container, obj, LV_ALIGN_CENTER, 0, 0);
    lv_obj_t *canvas = lv_canvas_create(container, NULL);
    lv_obj_set_click(canvas, false);
    lv_obj_set_size(canvas, lv_obj_get_width(obj), lv_obj_get_height(obj));
    lv_canvas_set_buffer(canvas, NULL, lv_obj_get_width(obj), lv_obj_get_height(obj), LV_IMG_CF_TRUE_COLOR);
    lv_obj_set_style_local_bg_opa(canvas, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);

    /* 设置画布的绘图函数 */
    lv_obj_set_draw_cb(canvas, (lv_obj_draw_cb_t)draw_rotated_button);

    /* 设置旋转角度 */
    lv_obj_set_angle(container, angle);

    /* 将按钮移动到容器中 */
    lv_obj_set_parent(obj, container);
    lv_obj_set_size(obj, 0, 0);
    lv_obj_align_origo(obj, container, LV_ALIGN_CENTER, 0, 0);
}

int main(void) {
    lv_init();

    /* 创建一个按钮 */
    lv_obj_t *button = lv_btn_create(lv_scr_act(), NULL);
    lv_btn_set_fit(button, LV_FIT_TIGHT);
    lv_obj_t *label = lv_label_create(button, NULL);
    lv_label_set_text(label, "Button");

    /* 旋转按钮 */
    rotate_widget(button, 90);

    while (1) {
        lv_task_handler();
        lv_tick_inc(5);
        usleep(5000);
    }

    return 0;
}

上述代码将创建一个按钮部件并将其旋转90度。你可以根据自己的需要修改旋转角度和部件类型。请确保在使用LVGL 8.2版本时,代码与LVGL库和配置文件的版本兼容。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^