LVGL8的窗口切换方式

LVGL8实现两个窗口的切换方式:
方法一:切换到窗口2时,删除窗口1的容器,这样可以删除窗口1下的所有子对象,这种方式适用于运存较小的设备

方法二:显示窗口1之前给窗口2的容器设置LV_OBJ_FLAG_HIDDEN隐藏属性,显示窗口2之前给窗口1的容器设置LV_OBJ_FLAG_HIDDEN隐藏属性

还是通过codeblock来模拟代码的运行,代码如下:

#define HIDDEN_WIN  (0)
static lv_obj_t *win1_contanier = NULL;
static lv_obj_t *win2_contanier = NULL;

static void win_btn_event_callback1(lv_event_t* event);
static void win_btn_event_callback2(lv_event_t* event);


static void show_button_win1()
{
    static lv_style_t obj_style;
    lv_style_reset(&obj_style);
    lv_style_init(&obj_style); // 初始化按钮样式
    lv_style_set_radius(&obj_style, 0); // 设置样式圆角弧度

    lv_obj_t * btn =NULL;
    win1_contanier = lv_obj_create(lv_scr_act());  // 基于屏幕创建一个和屏幕大小一样的容器win1_contanier
    if (win1_contanier != NULL)
    {
        lv_obj_set_style_bg_color(win1_contanier, lv_palette_main(LV_PALETTE_RED), 0);
        lv_obj_set_size(win1_contanier, 800, 480);
        lv_obj_add_style(win1_contanier, &obj_style, 0);

        btn = lv_btn_create(win1_contanier);
        if (btn != NULL)
        {
            lv_obj_set_size(btn, 100, 50);
            lv_obj_add_event_cb(btn, win_btn_event_callback1, LV_EVENT_ALL, NULL); // 给对象添加CLICK事件和事件处理回调函数
            lv_obj_center(btn);

            lv_obj_t *label = lv_label_create(btn); // 给按钮添加标签
            if (label != NULL)
            {
                lv_label_set_text(label, "Button1"); // 设置标签文本
                lv_obj_center(label); // 标签居中显示
            }
        }
     }
}


static void show_button_win2()
{
    static lv_style_t obj_style;
    lv_style_reset(&obj_style);
    lv_style_init(&obj_style); // 初始化按钮样式
    lv_style_set_radius(&obj_style, 0); // 设置样式圆角弧度

    lv_obj_t * btn =NULL;
    win2_contanier = lv_obj_create(lv_scr_act()); // 基于屏幕创建一个和屏幕大小一样的容器win2_contanier
    if (win2_contanier != NULL)
    {
        lv_obj_set_style_bg_color(win2_contanier, lv_palette_main(LV_PALETTE_BLUE), 0);
        lv_obj_set_size(win2_contanier, 800, 480);
        lv_obj_add_style(win2_contanier, &obj_style, 0);

        btn = lv_btn_create(win2_contanier);
        if (btn != NULL)
        {
            lv_obj_set_size(btn, 100, 50);
            lv_obj_add_event_cb(btn, win_btn_event_callback2, LV_EVENT_ALL, NULL); // 给对象添加CLICK事件和事件处理回调函数
            lv_obj_center(btn);
            lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), 0);

            lv_obj_t *label = lv_label_create(btn); // 给按钮添加标签
            if (label != NULL)
            {
                lv_label_set_text(label, "Button2"); // 设置标签文本
                lv_obj_center(label); // 标签居中显示
            }
        }
     }
}


static void win_btn_event_callback1(lv_event_t* event)
{
    lv_event_code_t code = lv_event_get_code(event);
    if (code == LV_EVENT_CLICKED)
    {
#if HIDDEN_WIN
        // 给窗口1的容器添加隐藏属性,清除窗口2的隐藏属性
        lv_obj_add_flag(win1_contanier, LV_OBJ_FLAG_HIDDEN);
        lv_obj_clear_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN);
#else
        // 删除窗口1的win1_contanier容器,这样就可以把win1_contanier上的子对象全部删除,然后显示窗口2
        lv_obj_del(win1_contanier);
        show_button_win2();
#endif
    }
}


static void win_btn_event_callback2(lv_event_t* event)
{
    lv_event_code_t code = lv_event_get_code(event);
    if (code == LV_EVENT_CLICKED)
    {
#if HIDDEN_WIN
        // 给窗口2的容器添加隐藏属性,清除窗口1的隐藏属性
        lv_obj_add_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN);
        lv_obj_clear_flag(win1_contanier, LV_OBJ_FLAG_HIDDEN);
#else
        // 删除窗口2的win2_contanier容器,这样就可以把win2_contanier上的子对象全部删除,然后显示窗口1
        lv_obj_del(win2_contanier);
        show_button_win1();
#endif
    }
}


void lv_win_switch_main()
{
    show_button_win1();
#if HIDDEN_WIN
    show_button_win2();
    // 给窗口2的容器添加隐藏属性
    lv_obj_add_flag(win2_contanier, LV_OBJ_FLAG_HIDDEN);
#endif
}

运行效果:

### 调整LVGL消息窗口中按钮的位置 在LVGL的消息窗口(`lv_msgbox`)设计中,默认情况下,按钮会按照预设的布局排列。如果希望自定义按钮的位置,则可以通过修改控件的样式和布局来实现更灵活的设计。 #### 方法一:通过 `lv_obj_set_pos()` 和 `lv_obj_align()` 可以直接调用 `lv_obj_set_pos()` 或者 `lv_obj_align()` 来调整按钮的具体位置。以下是具体操作方法: 1. 获取消息窗口中的按钮对象。 2. 使用上述函数重新定位这些按钮。 ```c // 假设 msgbox 是已经创建好的消息窗口对象 lv_obj_t *btns[] = { lv_msgbox_get_button(msgbox, 0), // 获取第一个按钮 lv_msgbox_get_button(msgbox, 1) // 获取第二个按钮 }; // 设置按钮的位置 if (btns[0]) { lv_obj_set_pos(btns[0], 50, 150); // 将第一个按钮放置到指定坐标 } if (btns[1]) { lv_obj_align(btns[1], btns[0], LV_ALIGN_OUT_RIGHT_MID, 20, 0); // 对齐到第一个按钮右侧 } ``` 这种方法适用于简单的场景,能够快速改变单个按钮的位置[^1]。 --- #### 方法二:重写默认布局逻辑 对于更加复杂的布局需求,可以考虑替换默认的布局方式。例如,在创建消息框时手动设置其子对象的布局模式为网格或其他形式。 ```c // 创建一个带有自定义布局的消息框 lv_obj_t *msgbox = lv_msgbox_create(parent, NULL); lv_obj_set_layout(msgbox, LV_LAYOUT_GRID); // 更改为网格布局 // 添加按钮并分配网格单元格 lv_obj_t *ok_btn = lv_msgbox_add_btns(msgbox, "OK", NULL); lv_obj_set_grid_cell(ok_btn, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1); lv_obj_t *cancel_btn = lv_msgbox_add_btns(msgbox, "Cancel", NULL); lv_obj_set_grid_cell(cancel_btn, LV_GRID_ALIGN_END, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); ``` 这种方式允许开发者完全控制每个按钮占据的空间比例以及相对关系[^2]。 --- #### 方法三:嵌套容器管理复杂结构 当需要非常精细地定制多个按钮之间的间距或者方向时,还可以引入额外的一层容器作为中介载体。 ```c // 新建一个水平盒子用于承载所有按钮 lv_obj_t *container = lv_cont_create(lv_scr_act(), NULL); lv_cont_set_fit(container, LV_FIT_TIGHT); lv_cont_set_layout(container, LV_LAYOUT_ROW_MID); // 向该盒子里依次加入各个单独的按键实例 for(int i=0;i<NUM_BUTTONS;i++) { char buf[8]; sprintf(buf,"Btn %d",i+1); lv_obj_t *temp_btn = lv_btn_create(container,NULL); lv_label_set_text(lv_btn_get_child(temp_btn,0),buf); } // 把整个包含器挂载回原始弹窗主体部分下方区域即可完成最终组装工作流程图如下所示: lv_obj_add_event_cb(container,event_handler,LV_EVENT_ALL,msgbox); ``` 这里利用了一个新的父级元素——容器,将所有的按钮都放入其中统一处理后再附加至目标视图之上[^3]。 --- ### 总结 以上三种方案分别针对不同程度的需求提供了相应的解决策略。简单场合下推荐直接运用API接口设定绝对数值;追求灵活性则应尝试切换不同的布局算法;而对于极其特殊的情况来说构建专属框架无疑是最优解法之一。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值