How to use the lv_obj_set_user_data function

Important: unclear posts may not receive useful answers.

Before posting

  • Get familiar with Markdown to format and structure your post
  • Be sure to update lvgl from the latest version from the master branch.
  • Be sure you have checked the FAQ and read the relevant part of the documentation.
  • If applicable use the Simulator to eliminate hardware related issues.

Delete this section if you read and applied the mentioned points.


I’m coding a screen transition program using ESP32 and ili9488.
I had chat gpt create a sample program for simple screen transitions, but I cannot switch to the next screen even if I press the next button.

I found that the return value of lv_obj_get_user_data of the called handler was NULL.

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

ESP32 & ili9488

What LVGL version are you using?


What do you want to achieve?

I want to move to the next screen.
I would like to know if there is really no problem with this coding.

What have you tried so far?

of the called handler

(lv_obj_t *)lv_obj_get_user_data(btn)

I see that this return value is NULL.

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.

The code block(s) should be formatted like:

void screen_setup() {

    screen1 = lv_obj_create(NULL);

    screen2 = lv_obj_create(NULL);

    screen3 = lv_obj_create(NULL);

    screen4 = lv_obj_create(NULL);


    lv_timer_create(update_clock, 1000, NULL);

void add_navigation_buttons(lv_obj_t *scr, lv_obj_t *next_screen, lv_obj_t *prev_screen) {
    lv_obj_t *btn_next = lv_btn_create(scr);
    lv_obj_set_size(btn_next, 100, 50);
    lv_obj_align(btn_next, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
    lv_obj_set_user_data(btn_next, next_screen);
    lv_obj_add_event_cb(btn_next, btn_event_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_next = lv_label_create(btn_next);
    lv_label_set_text(label_next, "Next");

    lv_obj_t *btn_back = lv_btn_create(scr);
    lv_obj_set_size(btn_back, 100, 50);
    lv_obj_align(btn_back, LV_ALIGN_BOTTOM_LEFT, 10, -10);
    lv_obj_set_user_data(btn_back, prev_screen);
    lv_obj_add_event_cb(btn_back, btn_event_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_t *label_back = lv_label_create(btn_back);
    lv_label_set_text(label_back, "Back");

void btn_event_cb(lv_event_t *e) {

    Serial.println("btn_event_cb start");

    #if 1
    lv_obj_t *btn = lv_event_get_target(e);

    // デバッグ情報の出力
    if (btn != NULL) {
        Serial.println("Event target (button) is not NULL");
        // さらに、ボタンに関する詳細情報を出力できます
    } else {
        Serial.println("Event target (button) is NULL");

    lv_obj_t *next_screen = (lv_obj_t *)lv_obj_get_user_data(btn);

    // デバッグ情報の出力
    if (next_screen != NULL) {
        Serial.println("next_screen is not NULL");
    } else {
        Serial.println("next_screen is NULL");

    if (next_screen != NULL) {

    Serial.println("btn_event_cb end");

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

Perhaps the EVENT handled by the btn_event_cb() is generated not by the button but by another element, for example its parent