LVGL:拓展部件——消息框 lv_msgbox

概述

消息框表现为一种弹出式的用户界面元素。当需要向用户显示信息、警告或请求确认时,会暂时覆盖部分或全部屏幕以展示消息内容。

消息框中的文本内容能够自动换行以适应空间大小,并且消息框的高度会根据实际包含的文本内容及按钮数量自动调整,确保所有内容都被适当地显示在框内。

消息框具有两种模式:

  • 模态:消息框会阻止用户点击屏幕上的其他区域,直到用户对消息框做出响应为止。
  • 非模态:用户可以在查看消息的同时操作界面的其他部分,不会被消息框阻断交互。

包含组件元素

消息框的各个组成部分:

  • 背景:是一个基本的对象容器 lv_obj,它为消息框提供了基础的布局和样式设定。
  • 关闭按钮:如果消息框包含了关闭按钮,该按钮是通过 lv_btn 对象实现的。
  • 标题与文本:消息框中的标题和正文内容都是使用 lv_label 组件来显示的。
  • 按钮:消息框底部用于用户交互的一系列按钮是由 lv_btnmatrix 组件构建的。lv_btnmatrix 允许创建多列按钮,并可以对单个按钮进行独立的样式和功能设置。

使用示例

// 消息框事件处理器
void msgbox_event_handler(lv_event_t *event)
{
    lv_event_code_t code = lv_event_get_code(event);
    lv_obj_t * mbox = lv_event_get_current_target(event);
    if(code == LV_EVENT_VALUE_CHANGED)
    {
        // 获取被点击的按钮索引
        int active_btn_index = lv_msgbox_get_active_btn(mbox);

        // 获取被点击的按钮文本
        const char * active_btn_text = lv_msgbox_get_active_btn_text(mbox);
        cout << active_btn_text <<std::endl;

        // 根据点击的按钮进行相应操作
        if(strcmp(active_btn_text, "Ok") == 0)
        {
            LV_LOG_USER("Ok button clicked.\n");
        }
        else if(strcmp(active_btn_text, "Cancel") == 0)
        {
            LV_LOG_USER("Cancel button clicked.\n");
            lv_msgbox_close(mbox);// 如果需要,可以在此处关闭消息框
        }
    }
}

int main(int argc, char **argv)
{
    lv_init();
    hal_init();

    lv_log_register_print_cb(esp32_log_cb);

    {
        static const char * btns[] = {"Ok", "Cancel", ""};

        lv_obj_t * mbox = lv_msgbox_create(lv_scr_act(), "Title", "This is a message box.", btns, true);
        lv_obj_add_event_cb(mbox, msgbox_event_handler, LV_EVENT_ALL, NULL);
        lv_obj_center(mbox);
    }

    while (1)
    {
        lv_task_handler();
        usleep(5 * 1000);
    }

    return 0;
}

当点击消息框中的任意一个按钮时,该按钮会发送 LV_EVENT_VALUE_CHANGED 事件。在LVGL中,按钮矩阵的事件传播模式被设置为 LV_OBJ_FLAG_EVENT_BUBBLE,也就是即使事件首先由按钮触发,它也会向上传递到消息框本身。

在事件处理器中:

  • 可以使用 lv_event_get_target(e) 获取触发事件的实际对象,即按钮矩阵。
  • 可以使用 lv_event_get_current_target(e) 可以获取当前处理事件的目标对象,也就是消息框本身。

相关函数

1、lv_obj_t *lv_msgbox_create(lv_obj_t *parent, const char *title, const char *txt, const char *btn_txts[], bool add_close_btn);

创建一个消息框对象的函数。

  • parent:指向父容器对象的指针,如果传入 NULL,则会创建一个全屏模态的消息框
  • title:消息框标题。
  • txt:消息框正文文本。
  • btn_txts:按钮文本数组,数组中的每个元素代表一个按钮上的文本,数组以空字符串 ("") 结束。例如:{"Yes", "No", ""} 表示创建两个按钮,分别标注为“是”和“否”。
  • add_close_btn:是否要在消息框上添加一个关闭按钮。

全屏模态消息框:

2、lv_obj_t *lv_msgbox_get_title(lv_obj_t *obj)

获取消息框的标题对象。通过这个指针可以修改标题内容、样式等属性。

3、lv_obj_t *lv_msgbox_get_close_btn(lv_obj_t *obj)

获取消息框上的关闭按钮对象。可以使用这个指针对关闭按钮进行事件绑定或样式调整等操作。

4、lv_obj_t *lv_msgbox_get_text(lv_obj_t *obj)

获取消息框主体文本区域的对象(lv_label)。可以使用它更改或获取消息框内的详细文本信息。

5、lv_obj_t *lv_msgbox_get_content(lv_obj_t *obj)

获取消息框的内容对象。使用它可以自定义内容布局或其他操作。

        static const char * btns[] = {"Ok", "Cancel", ""};

        lv_obj_t * mbox = lv_msgbox_create(lv_scr_act(), "Title", "", btns, true);
        lv_obj_add_event_cb(mbox, msgbox_event_handler, LV_EVENT_ALL, NULL);
        lv_obj_center(mbox);

        lv_obj_t *content_area = lv_msgbox_get_content(mbox);

        // 在内容区域内添加自定义对象(例如:一个标签)
        lv_obj_t *custom_label = lv_label_create(content_area);
        lv_label_set_text(custom_label, "Custom text added to the content area.");
        lv_obj_set_width(custom_label,250);

6、lv_obj_t *lv_msgbox_get_btns(lv_obj_t *obj)

获取消息框底部按钮矩阵对象(lv_btnmatrix)。使用它可以访问和控制消息框的所有按钮,包括但不限于添加事件处理器、修改按钮文字或样式等。

7、uint16_t lv_msgbox_get_active_btn(lv_obj_t *mbox)

获取消息框中当前被选中的按钮的索引。

返回当前被选中的按钮在按钮矩阵中的索引。如果没有任何按钮被选中,则返回 LV_BTNMATRIX_BTN_NONE

8、const char *lv_msgbox_get_active_btn_text(lv_obj_t *mbox)

获取消息框中当前被选中的按钮的文本。

9、void lv_msgbox_close(lv_obj_t *mbox)

关闭并删除指定的消息框对象。执行此操作后,消息框将从屏幕上消失,并且与之相关的资源会被释放。

10、void lv_msgbox_close_async(lv_obj_t *mbox)

用于关闭指定的消息框对象,并且是以异步的方式进行的。异步函数意味着函数会立即返回,而不会等待关闭操作完成。这样可以避免在操作过程中堵塞用户界面。

当调用此函数时,它并不会立即删除并释放与消息框相关的资源,而是将关闭消息框的操作放入到事件队列中,使其在下一个事件处理周期执行。这样可以避免在当前UI更新过程中直接销毁消息框导致的界面刷新异常或其他潜在问题。

bool need_create_popup = false;
lv_obj_t *msgbox_closed_popup;

// 定义一个定时器回调函数,用于延迟关闭弹出窗口
static void close_popup_timer_cb(lv_timer_t *timer)
{
    // 关闭弹出窗口
    need_create_popup = false;
    lv_msgbox_close_async(msgbox_closed_popup);
    lv_timer_del(timer); // 删除定时器
}

// 定义一个定时器回调函数,用于延迟创建新的弹出窗口
static void create_popup_timer_cb(lv_timer_t *timer)
{
    // 创建新的弹出窗口
    static const char * btns[] = {""};
    msgbox_closed_popup = lv_msgbox_create(lv_scr_act(), "notice", "Message box closed", btns, false);
    lv_obj_center(msgbox_closed_popup);
    lv_obj_add_flag(msgbox_closed_popup, LV_OBJ_FLAG_HIDDEN);//隐藏对象

    lv_timer_del(timer);// 删除定时器
    need_create_popup = true;

    // 创建一个定时器,延迟三秒后关闭弹出窗口
    lv_timer_create(close_popup_timer_cb, 3000, NULL);
}

// 消息框事件处理器
void msgbox_event_handler(lv_event_t *event)
{
    lv_event_code_t code = lv_event_get_code(event);
    if(code == LV_EVENT_VALUE_CHANGED)
    {
        lv_obj_t * mbox = lv_event_get_current_target(event);

        const char * active_btn_text = lv_msgbox_get_active_btn_text(mbox);// 获取被点击的按钮文本

        // 根据点击的按钮进行相应操作
        if(strcmp(active_btn_text, "Ok") == 0)
        {
            LV_LOG_USER("Ok button clicked.\n");
        }
        else if(strcmp(active_btn_text, "Cancel") == 0)
        {
            LV_LOG_USER("Cancel button clicked.\n");
            lv_msgbox_close_async(mbox);
            lv_timer_create(create_popup_timer_cb, 200, NULL);
        }
    }
}

int main(int argc, char **argv)
{
    lv_init();
    hal_init();

    lv_log_register_print_cb(esp32_log_cb);

    {
        static const char * btns[] = {"Ok", "Cancel", ""};
        lv_obj_t * mbox = lv_msgbox_create(lv_scr_act(), "Title", "this is msg", btns, true);
        lv_obj_add_event_cb(mbox, msgbox_event_handler, LV_EVENT_ALL, NULL);
        lv_obj_center(mbox);
    }

    // ProjectManager_Run_Lvgl::getInstance()->openProject();

    while (1)
    {
        lv_task_handler();
        usleep(5 * 1000);

        if(need_create_popup)
        {
            lv_obj_clear_flag(msgbox_closed_popup, LV_OBJ_FLAG_HIDDEN);//取消隐藏
            need_create_popup = false;
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值