Close msgbox Event

Is there a way to flag/register/link event to the close button (x) of a msgbox?

LV_EVENT_CANCEL doesn’t seem to work.

Perhaps there is a different method to verify if a message box is active or inactive/closed?

Thank you in advance!

You can send manually close button event.

lv_event_send(close_btn, LV_EVENT_CLICKED, NULL);

Or you can hide

lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN);

Or you can delete window object.

lv_obj_del(win);

Thank you for your reply @martin023

Unfortunately I can’t seem to get it to work.

Situation:

  • for one msg box I need to close the message box via added buttons, and load another screen.
  • for another msg box, without buttons, I need to preform a task once the “close msg box/X button” is clicked.

to keep it simple, I figured you might be able to point out how all this can be achieved in 1 msg box.
Below is the example from the LVGL website, could you help me out by pointing out the following:
How do I link click events to the “apply” en “close” button?
How do I link an event on the “X/close msgbox” button in the upper right corner?

Thank you so much in advance :pray:t3: !

static void event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    LV_UNUSED(obj);
    LV_LOG_USER("Button %s clicked", lv_msgbox_get_active_btn_text(obj));
}

void lv_example_msgbox_1(void)
{
    static const char * btns[] = {"Apply", "Close", ""};

    lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", btns, true);
    lv_obj_add_event(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_center(mbox1);
}

Hi @JvL_1 ,

You need to attach an event callback to the close button on the message box as well see code below…

It looks like your using the latest master branch (v9 development code) so this code only applies to that version it is untested in v8…

static void event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    LV_UNUSED(obj);
    LV_LOG_USER("Button %s clicked", lv_msgbox_get_active_btn_text(obj));
}

static void close_cb( lv_event_t * e ) {

	LV_LOG_USER("Close Button clicked");

}

void lv_example_msgbox(void)
{
    static const char * btns[] = {"Apply", "Close", ""};

    lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", btns, true);
    lv_obj_add_event(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event(((lv_msgbox_t *)mbox1)->close_btn, close_cb, LV_EVENT_PRESSED, NULL);

    lv_obj_center(mbox1);
}

I hope that makes sense.

Kind Regards,

Pete

Hi @pete-pjb

First of all thank you for your time and reply.
I am using version 8.3.4.

The closing (X) event works, thanks a lot for that!
About the “apply” & “close” buttons in the example.
How do I distinguish between which of them is clicked within void event_cb?
It seems to be handled different than with buttons on a regular screen vs buttons within a message box.

(like if apply is clicked do this, if close is clicked do this)

(sorry beginner in LVGL here, thank you for your patience and willingness to explain)

Kind regards,
Joël

Hi @JvL_1 ,

You can either use strcmp() on the name text or get the id of the button where the first in the list is 0 and the next 1 and so on…

I am confused by your versions as the code you have posted definitely will not compile on v8, is what you posted definitely what you are using in your working code? :grinning:

Kind Regards,

Pete

Hi @pete-pjb

No I noticed ( earlier while trying and testing) that

lv_obj_add_event(mbox1,

needs to be

lv_obj_add_event_cb(mbox1,

So how I am trying to test my code (again just a beginner in LVGL) is putting in serial prints, to verify where I am in the code:

static void event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    LV_UNUSED(obj);
    LV_LOG_USER("Button %s clicked", lv_msgbox_get_active_btn_text(obj));
    Serial.println("Other Buttons clicked");
}

static void close_cb( lv_event_t * e ) {

  LV_LOG_USER("Close Button clicked");
  Serial.println("Close Button clicked");

}

void lv_example_msgbox_1(void)
{
    static const char * btns[] = {"Apply", "Close", ""};

   Serial.println("Message box opened");

    lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", btns, true);
    lv_obj_add_event_cb(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event_cb(((lv_msgbox_t *)mbox1)->close_btn, close_cb, LV_EVENT_PRESSED, NULL);

    lv_obj_center(mbox1);
}

But as you can see, I am not able (yet) to distinguish if “apply” or “close” was clicked.
Will look into strcmp() as you suggested, or button ID.

Thank you for your time and help.
Kind regards,
Joël

Hi @JvL_1 ,

Okay no worries…

So in version 8 the event is coming from the button matrix on the message box so to use the lv_msgbox_get_active_btn_text() function you need to get the parent of the button matrix as follows:

static void event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_obj_get_parent( lv_event_get_target(e) );
    const char *ptr = lv_msgbox_get_active_btn_text(obj);
    LV_LOG_USER("Button %s clicked", ptr);
    if( !strcmp( "Apply", ptr ) ) {
        Serial.println("Apply");
    } else if( !strcmp("Close", ptr ) ) {
        Serial.println("Close");
    }

}


static void close_cb( lv_event_t * e )
{

  LV_LOG_USER("Close Button clicked");
  Serial.println("Message Box Close Button clicked");

}

void lv_example_msgbox(void)
{
    static const char * btns[] = {"Apply", "Close", ""};

    Serial.println("Message box opened");

    lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", btns, true);
    lv_obj_add_event_cb(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event_cb(((lv_msgbox_t *)mbox1)->close_btn, close_cb, LV_EVENT_PRESSED, NULL);

    lv_obj_center(mbox1);
}

So hopefully this should work now if you paste it into your environment.

Kind Regards,

Pete

Hi @pete-pjb

Thank you for your efforts in teaching me :slight_smile:

After a few minor adjustments to the code, I am able to successfully test its functionality.
Can’t wait to alter it and use it in my actual project!
One last thing, how do I get the “apply” and “close” button to close the message box?
adding lv_msgbox_close(mbox1); to the if/else if statements crashes the code.

Your help is greatly appreciated!
Kind regards,
Joël

Hi @JvL_1 ,

It seems I posted the reply uncompleted before my apologies I am rushing around a bit today and got interrupted! :crazy_face:

I have corrected the previous post and here it is again with the added close call:

static void event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_obj_get_parent( lv_event_get_target(e) );
    const char *ptr = lv_msgbox_get_active_btn_text(obj);
    LV_LOG_USER("Button %s clicked", ptr);
    if( !strcmp( "Apply", ptr ) ) {
        Serial.println("Apply");
    } else if( !strcmp("Close", ptr ) ) {
        Serial.println("Close");
        lv_msgbox_close(obj);
    }

}

static void close_cb( lv_event_t * e )
{

  LV_LOG_USER("Close Button clicked");
  Serial.println("Message Box Close Button clicked");

}

void lv_example_msgbox(void)
{
    static const char * btns[] = {"Apply", "Close", ""};

    Serial.println("Message box opened");

    lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", btns, true);
    lv_obj_add_event_cb(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event_cb(((lv_msgbox_t *)mbox1)->close_btn, close_cb, LV_EVENT_PRESSED, NULL);

    lv_obj_center(mbox1);
}

Kind Regards,

Pete

1 Like

@pete-pjb you saved my project and learned me things along the way.
Your help is greatly appreciated, thanks a lot!
Joël