LVGL V8.3 IMGBTN could not change image when pressed

Description

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

ESP32 WT32-SC01 touch screen

What LVGL version are you using?

V8.3

What do you want to achieve?

Change images between released/pressed one same button. Which is: when not pressing any button, the image button shows RPLAY_N, when pressed, shows RPLAY_P constantly.

What have you tried so far?

One more question: The possible states are:

  • LV_IMGBTN_STATE_RELEASED
  • LV_IMGBTN_STATE_PRESSED
  • LV_IMGBTN_STATE_DISABLED
  • LV_IMGBTN_STATE_CHECKED_RELEASED
  • LV_IMGBTN_STATE_CHECKED_PRESSED
  • LV_IMGBTN_STATE_CHECKED_DISABLED

I do not understand the difference between former 3 states and later 3?? What exactly does “CHECKED” mean?

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

/You code here/
LV_IMG_DECLARE(RPLAY_P);
LV_IMG_DECLARE(RPLAY_N);
lv_obj_t *BT_RPLAY = lv_imgbtn_create(lv_scr_act());
lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_RELEASED,NULL, &RPLAY_N, NULL);
lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_PRESSED, NULL, &RPLAY_N, NULL);
lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_CHECKED_RELEASED, NULL, &RPLAY_P, NULL);
lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_CHECKED_PRESSED, NULL, &RPLAY_P, NULL);

Thanks in advance!!

I’m following the example: Image button (lv_imgbtn) — LVGL documentation but after uploading, no image change when pressing button.

The documentation you have linked to is for version 7.11 and not 8.3. You need to change what version of the documentation you are using, that can be done at the top left of the webpage.

I tried v8.3 at Image button (lv_imgbtn) — LVGL documentation but does not work too.

can you post some code so I can look at it to see what you are going?

1 Like

Pls see attached code in the first post. My purpose is to show pic1, when clicking it, it shows me the other image and keeps the pic. I have example code in V7.1 but no example code in v8.3. The code in V7.1 does not work in V8.3. Pls help!

Hi @kaosun ,

The checked states are when you enable the ‘check-able’ flag which means when you click the button it stays in a pressed state until you press it again and then it will be unpressed again if that makes sense? In other words you can toggle the state of the button by clicking it…

To enable this in version 8 you can try this with your code snippet, (it may or maynot work):
(NOTE: I have changed the referenced images from your original)

    LV_IMG_DECLARE(RPLAY_P);
    LV_IMG_DECLARE(RPLAY_N);
    lv_obj_t *BT_RPLAY = lv_imgbtn_create(lv_scr_act());
    lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_RELEASED,NULL, &RPLAY_N, NULL);
    lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_PRESSED, NULL, &RPLAY_P, NULL);
    lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_CHECKED_RELEASED, NULL, &RPLAY_N, NULL);
    lv_imgbtn_set_src(BT_RPLAY, LV_IMGBTN_STATE_CHECKED_PRESSED, NULL, &RPLAY_P, NULL);
    lv_obj_add_flag(BT_RPLAY, LV_OBJ_FLAG_CHECKABLE );

Kind Regards,

Pete

Thanks Pete! I noticed you added the last line to my code. My test shows when I touch and press the button, the button can change to the other pic; however, when I stop touching, the button return to the original pic, cannot constantly show the second pic. Now my solution is adding the pic change in the button’s event handler, when hit the button, the handler will change the image to be the second one. Although I didn’t implement it like the example in V7.1 but it now works for me. Let me know if you have any other idea, I would like to implement it in other ways.

Hi @kaosun ,

I think there may be a bug. I will try and take a look at the lv_imgbtn sources tomorrow to try and locate the problem.

Kind Regards,

Pete

Hi @kaosun ,

Your work around is fine and will not cause any issues I can think of… it will be okay for the time being I am sure.

It does seem to me there may be a bug in the image button which is causing it not to respect the LV_OBJ_FLAG_CHECKABLE flag. I have looked into it, but I have not found the issue yet I will continue to investigate, but I am out of time right now. I will let you know when I have taken a further look.

I have also raised this as an issue on github here so others can take a look if they get time…

Kind Regards,

Pete

Hi @kaosun ,

A fix has been pushed here

It should work without the callback now.

Kind Regards,

Pete

Thanks a lot! If I need the button to do something else, like turn on a GPIO, the handler is still needed, right?
Now I have another issue. I created an image button DSL on GUI, it works well. Then I added another one DOLBY by same method, my screen just flash and nothing appears. Resource 20% RAM is used, 52% of flash is used so far. Pls help.

Code:
lv_obj_t *BT_Dolby;

LV_IMG_DECLARE(Dolby_OFF);

LV_IMG_DECLARE(Dolby_B);

LV_IMG_DECLARE(Dolby_C);

int Dolby_Count = 0;

lv_obj_t *BT_DSL;

LV_IMG_DECLARE(DSL_N);

LV_IMG_DECLARE(DSL_P);

int DSL_Count = 0;

// Dolby button
lv_imgbtn_set_src(BT_Dolby, LV_IMGBTN_STATE_RELEASED, NULL, &Dolby_OFF, NULL);
lv_obj_add_event_cb(BT_Dolby, BT_REC_event_handler, LV_EVENT_ALL, NULL);          
lv_obj_set_pos(BT_Dolby, 400, 100);                            
lv_obj_set_size(BT_Dolby, 60, 26);                          

// DSL button
lv_imgbtn_set_src(BT_DSL, LV_IMGBTN_STATE_RELEASED, NULL, &DSL_N, NULL);
lv_obj_add_event_cb(BT_DSL, BT_DSL_event_handler, LV_EVENT_ALL, NULL);
lv_obj_set_pos(BT_DSL, 400, 150);   
lv_obj_set_size(BT_DSL, 60, 26);

//Dolby
static void BT_Dolby_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * btn = lv_event_get_target(e);
if(code == LV_EVENT_CLICKED) {
Dolby_Count++;
if(Dolby_Count % 3 == 1 ){lv_imgbtn_set_src(BT_Dolby, LV_IMGBTN_STATE_RELEASED, NULL, &Dolby_OFF, NULL); }
if(Dolby_Count % 3 == 2 ){lv_imgbtn_set_src(BT_Dolby, LV_IMGBTN_STATE_RELEASED, NULL, &Dolby_B, NULL); }
if(Dolby_Count % 3 == 3 ){lv_imgbtn_set_src(BT_Dolby, LV_IMGBTN_STATE_RELEASED, NULL, &Dolby_C, NULL); }

  }

}
//DSL
static void BT_DSL_event_handler(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t *btn = lv_event_get_target(e);
if (code == LV_EVENT_CLICKED)
{
DSL_Count++;
if(DSL_Count % 2 == 0 ){ lv_imgbtn_set_src(BT_DSL, LV_IMGBTN_STATE_RELEASED, NULL, &DSL_N, NULL); }
if(DSL_Count % 2 == 1 ){ lv_imgbtn_set_src(BT_DSL, LV_IMGBTN_STATE_RELEASED, NULL, &DSL_P, NULL); }

}

}

Each button image is 211KB with TRUE color, c format. I’ll have 17 imgbtns. Several images will fill all 512KB RAM of ESP32. Therefore, I tried converting images to TRUE_color Binary RGB332 but screen only shows me half grey box. Tried all other formats, neither worked for me. I’m looking for an efficient BIN format to reduce RAM occupation while work with imgbtn. Pls help!

Handled. In image converter, you should carefully choose the output format of the images.