Changing state of object in event of another one

Hello @kisvegabor, @pete-pjb @embeddedt ,

I wanna ask about the function lv_obj_add/clear_state , which effect on events they have? I give an example to explain what i want to understand :

  • two checkable buttons, both have their events the way in code snippet bellow,

the events created bellow will be trigerred just in case i press on button to change state and the function lv_obj_clear_state doesn’t trigger the event LV_EVENT_VALUE_CHANGED of the second one, is this normal ?

In docs nothing is talking about events triggered in changing states, events are triggered when states are automatically changed by the library but it doesn’t work when we do it manually, is it developped this way ? if it’s the case do you suggest to add lv_event_send to the object concerned ?

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

eclipse simulator (windows)

What LVGL version are you using?

8.3.3

What do you want to achieve?

trigger events by changing state of object by another one manually

Code to reproduce

lv_obj_t *button1;
lv_obj_t *button2;
lv_obj_t *object1;
lv_obj_t *object2;

void event_button1_cb(lv_event_t * e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    lv_obj_t * target = lv_event_get_target(e);
   
  if(event_code == LV_EVENT_VALUE_CHANGED && lv_obj_has_state(target, LV_STATE_CHECKED)) {
        lv_obj_clear_state(button2,LV_STATE_CHECKED);
        lv_obj_clear_flag(object1, LV_OBJ_FLAG_HIDDEN);
    	}

 if(event_code == LV_EVENT_VALUE_CHANGED &&  !lv_obj_has_state(target, LV_STATE_CHECKED)) {

   lv_obj_add_flag(object1, LV_OBJ_FLAG_HIDDEN);    		
}

void event_button2_cb(lv_event_t * e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    lv_obj_t * target = lv_event_get_target(e);
   
  if(event_code == LV_EVENT_VALUE_CHANGED && lv_obj_has_state(target, LV_STATE_CHECKED)) {
        lv_obj_clear_state(button1,LV_STATE_CHECKED);
        lv_obj_clear_flag(object2, LV_OBJ_FLAG_HIDDEN);
    	}

 if(event_code == LV_EVENT_VALUE_CHANGED &&  !lv_obj_has_state(target, LV_STATE_CHECKED)) {
   lv_obj_add_flag(object2, LV_OBJ_FLAG_HIDDEN);   
   }

...
...
    lv_obj_add_event_cb(button1, event_button1_cb, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(button2, event_button2_cb, LV_EVENT_ALL, NULL);

Hi @Zebra067 ,

I think to do things the way you are trying here you need to add these lines after you create the buttons:

	lv_obj_add_flag(button1, LV_OBJ_FLAG_CHECKABLE);
	lv_obj_add_flag(button2, LV_OBJ_FLAG_CHECKABLE);

This should enable the events to fire correctly.
See docs here.

I hope that helps.

Kind Regards,

Pete

Hi @pete-pjb,

Obviously, buttons should be checkable otherwise it won’t work,

for the example i gave events are triggered when i press a button,
press the button1 to be checked ==event_button1_cb==> unchecking button2 by lv_obj_clear_state(button2,LV_STATE_CHECKED); when this happens it should trigger event_button2_cb because the value is changing checked to default
so changing state of an object should trigger the event LV_EVENT_VALUE_CHANGED, and i want to understand, if we change state manually is it going to trigger events automatically by Library? or i should add after all conditions lv_event_send(button2,LV_EVENT_VALUE_CHANGED,NULL);

(as i did in example i sent to you by email, I used LV_EVENT_REFRESH, I’m waiting for your feedback when you have time)

Here I just find out that changing state manually (of a checkable object) doesn’t trigger LV_EVENT_VALUE_CHANGED, and it’s triggered just in case of we pressed on it (here events works correctly by library) , I wondered if it’s not a bug or it was designed to work like that

Thank you Pete,

Kind Regards

Zebra,

Hi @Zebra067 ,

I think we should ask @kisvegabor to confirm whether this is expected behaviour, the library code suggests it probably is working as intended and you probably should send the event yourself, but I could be wrong :slight_smile:

Hopefully I will get around to looking at your earlier request properly this week :blush: , I have been working away for a couple of weeks and I am still catching up after returning to my office. Thank you for your patience…

Kind Regards,

Pete

1 Like

Hi @pete-pjb,

That’s what i think too, i just get confused that i change state manually so it doesn’t trigger the event LV_EVENT_VALUE_CHANGED as it does in press of button, maybe it’s intended to another event, for that i asked for the effect of changing state manually.

Don’t worry about it, Thank you for your help, i appreciate

Kind regards,

Zebra

I see that lv_obj_add/clear_state doesn’t send event because it’s a basic function used in library before handling event and it helps to handle events by library, so as I see i should send event manually too in case of using this function,

I create a function this way :

//in header file
enum{
	ADD_STATE,
	CLEAR_STATE
};
void change_state(lv_obj_t * obj, lv_state_t state, int action);

//in c file
void change_state(lv_obj_t * obj, lv_state_t state, int action)
{
    if(action == ADD_STATE) lv_obj_add_state(obj, state);
    else if(action == CLEAR_STATE) lv_obj_clear_state(obj , state);
    else LV_LOG_USER("Action doesn't exist");

    lv_event_send(obj, LV_EVENT_VALUE_CHANGED, 0);
}

For now it’s working for check and uncheck, i didn’t tested it for focused or disabled as i don’t know if the LV_EVENT VALUE_CHANGED in other states or not

waiting for @kisvegabor’s answer concerning this subject, and if the event which is used for the change of state is indeed LV_EVENT_VALUE_CHANGED,

Kind regards

Zebra,

1 Like

Hi,

It’s the intended behavior, i.e. to not send events on manual changes. E.g. lv_slider_set_value() won’t send VALUE_CHANGED event either.

I was thinking a lot about it and in the earlier days of LVGL and I have tried both. In the end I kept with the no event version mainly because it’s more flexible. If the events were included you couldn’t prevent firing them. However you always have the opportunity to send the events manually.

1 Like

I see, Thank you for your answer