How to handle multiple user to one event

Description

I try using one event with different user_data (hide and unhide multiple object by applying an event to button matrix) ,

as mentioned in docs here

The problem i have is that i don’t know how to handle user inside the event callback, all events callbacks will be called and it’s having already a user_data, and I can’t change the user inside.

Can someone help me to resolve this? ?

What MCU/Processor/Board and compiler are you using?

codeblocks simulator

What LVGL version are you using?

8.01

What do you want to achieve?

handle different user_data with same callback

What have you tried so far?

i tried to apply event on button matrix, inside the event callback I made a condition if

        uint32_t id = lv_btnmatrix_get_selected_btn(obj);
            if(id == 0)user = num1;
            if(id == 1)user = num2;

it doesn’t work

In the page you link to, scroll down a bit further to the ‘Fields of lv_event_t’ section. There you will find the ‘lv_event_get_user_data()’ function that will give you whatever object reference you put in the ‘add event callback’ call.
Susan

Yes the lv_event_get_user_data() is used in simple event to get the user data,
the problem here is I don’t know how to make differences between user_data in event handling multiple user_data,
i gaved the example of button matrix, every button state checked need to be linked to page (like the tabview but with possibility to hide all page and have all buttons unchecked),

button matrix event in case of button is change_value would make this :

  • make one check button or uncheck all buttons
  • display objects related to button ID checked.
  • hide other objects related to other buttons unchecked

in case of button matrix i assume that we can’t apply event to every button individualy (they are virtual buttons) and there is no function to access to each button separatly,
I tried to apply lv_obj_get_child(btnm,1) where i add event but my application is crashing, see bellow

static void btnmatrix_my_cb(lv_event_t * e ) {

    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);
    lv_obj_t *user =lv_event_get_user_data(e);

    if(code == LV_EVENT_VALUE_CHANGED) {
        lv_state_t stat = lv_obj_get_state(obj);

    if(stat == LV_STATE_CHECKED) lv_obj_clear_flag(user,LV_OBJ_FLAG_HIDDEN);
    else lv_obj_add_flag(user,LV_OBJ_FLAG_HIDDEN);

    }
}
.
.

 lv_obj_add_event_cb(lv_obj_get_child(btnm,2),btnmatrix_my_cb,LV_EVENT_VALUE_CHANGED,num1);
   lv_obj_add_event_cb(lv_obj_get_child(btnm,2),btnmatrix_my_cb,LV_EVENT_VALUE_CHANGED,num2)

And i don’t know how to handle multiple users in one event_callback because the event_callback is called every event on target, and i can’t see how to make differences between users,

Maybe be i took a button matrix which is a little bit difficult to begin, but i’m sure there’s a way that i can’t see to make it work,

I don’t know if there is a way to link object states to other’s (the group option i didn’t get it well yet)

@pete-pjb, please, Can you take a look at this ?

Kind regards,

Zebra

Hi @Zebra067 ,

To get user data in an event as far as I can see you should use this function:
void * lv_event_get_user_data(lv_event_t * e)

I am not totally sure what you need to achieve here, is it something along the lines of this example in the docs?

Kind Regards,

Pete

Hi @pete-pjb,

Of course i use this in event callback, for one user_data (the last parameter in lv_obj_add_event_cb )

But as i saw in the docs that same event callback can be used for different user_data

and as the events are called in the order as they were added, i can’t make difference between user_data called inside event_callback,
it will be evident if i’ll apply same thing to all user_data for each event (i.e : hiding all object, )
but here i wanna choose what to do depending on buttons state(virtual button of button matrix) used,
as buttons on btnMatrix are not real objects so i can’t add event for each button separatly, i add event to the whole button matrix, so in event_callback i make difference between buttons by the ID (uint32_t id = lv_btnmatrix_get_selected_btn(obj);) of button but there’s no option to know which event is called to make differences between user_data.

I saw somewhere that @kisvegabor wanted to make button matrix in next versions with real buttons, i think because of cases like this, like we can’t apply events directly to buttons.
is what i want to achieve is impossible with the one in this version ?

I imagined that i could make a counter inside the event callback to know which event is called as i know the order of adding events to buttonmatrix, then i can make difference of user_data, but i should put it to zero when all events are called once.

I hope you understand what i mean,

stupid question : :sweat_smile: is there a way to link the state of an object to state of other without using events (like in creation of object) ?
I think my question is stupid because i never used any other GUI programming, i begin to learn with LVGL so i don’t really knows how it works in other libraries :slight_smile:

Kind regards,

Zebra

Hi @Zebra067 ,

I am sorry if I am being dumb but I am not sure I totally understand what you are trying to achieve. Can you describe your application, maybe create the layout with buttons and then describe what you want them to do? :smiley:

Without fully understanding your need could I suggest you might consider just creating your own matrix of buttons using discreet button objects and placing them in an lv_obj_t, would that enable you to more easily achieve your goals? There is no performance penalty I can think of if you do things this way, as long as you stick to the concepts we have discussed previously.

Kind Regards,

Pete

Hi @pete-pjb,

I’m sorry, it’s my bad, my explanation is not clear
I wanna have a navigation bar, like a tabview but with the option of uncheck all buttons and hide pages related with,

for example look at this site’s navigation toolbar
assuming this toolbar all buttons are unchecked


in the site web if your cursor is on a button it get’s to state checked and display a content as below

for my case i wanna make contents displayed if my bouton is checked and hide all if all boutons are unchecked,

I don’t know if you understand,

the issue for me if i use separate buttons i’ll should create a link between them to make just one bouton checked, I don’t know how to do this for now, (would it be by lv_event_send(obj, <EVENT_CODE> &some_data) ? ) , and for me i see that i will need handle multiple user_data with one event_callback to make just one bouton checked,

I’m just missing something in how I analyse the communication between objects,

Thank you

Kind regards,

Zebra

Hi @Zebra067 ,

Thanks for the clarification I have a better understanding now, is the menu you have shown as an example what you are wanting to reproduce?

I think there will be a way of doing this with a tabview or a collection of existing widgets but I will need some time to think about it. I’ll post back when I can.

Kind Regards,

Pete

1 Like

Hi @pete-pjb,

Yes it’s something like the example i showed, I need a toolbar that will make me show or hiding objects depending on state of buttons in toolbar, I tried at first to make customize tabview to make it possible to hide page and ancheck all buttons, but the structure of tabview doesn’t allow me to do that, (objects are placed by flexflow, and pages are placed one next to other that what make us scroll between pages, )

Yes i think too that it’s possible to make it work with a collection of existing widgets,

I’ll try to do it with real buttons grouped in container, and use lv_obj_get_parent & lv_obj_get_child in event callback to make a link between buttons that will permit make them one checked, i assume that’s possible,

I am sorry if I am being dumb and annoying, if you think my reflexion is in the wrong way, or if you have any idea please tell me, take your time.

I’m grateful you helped me so much already, so if you don’t have time don’t bother yourself.

Thank you so much Pete,

Zebra