Animations in lvgl branch micropython_v1.24.1-usermod?

I saw that lvgl micropython finally is upgrading to the v1.24 micropython version and I think is really good news for all of us. Before the best alternative was the kdschlosser, wich was amazing work too, but if we have something official is always better.

So, I was to build and make it work without any issues. The problem is of course that the micropython examples were removed from the web and now you need to translate manually the 9.x API from C to micropython. This worked for most of the examples I tried (with the help of the lv_mp.c file), but not for the animations.

Is there any plan to update the web examples with micropython code?
What is the API required for use the animations in micropython?

(Note: I builded my micropython image a week ago, so maybe its already fixed)

When I launch this micropython code, the system simply crashes, so I dont know why it fails. On the lv_mp.c I read:

/*
 * Function NOT generated:
 * Callback function 'lv_anim_exec_xcb_t exec_cb' must receive a struct pointer with user_data member as its first argument!
 * lv_anim_exec_xcb_t exec_cb
 */

Here is the py code:


import lvgl as lv

def anim_x_cb(obj, value):
    obj.set_x(value)

def sw_event_cb(e):
    sw = e.get_target_obj()
    label = e.get_user_data()
    
    if sw.has_state(lv.STATE.CHECKED):
        # Create animation to move label to the right
        a = lv.anim_t()
        a.init()
        a.set_var(label)
        a.set_values(label.get_x(), 100)
        a.set_duration(500)
        a.set_custom_exec_cb(anim_x_cb)
        a.set_path_cb(lv.anim_t.path_overshoot)
        a.start()
    else:
        # Create animation to move label off-screen to the left
        a = lv.anim_t()
        a.init()
        a.set_var(label)
        a.set_values(label.get_x(), -label.get_width())
        a.set_duration(500)
        a.set_custom_exec_cb(anim_x_cb)
        a.set_path_cb(lv.anim_t.path_ease_in)
        a.start()

def lv_example_anim_1():
    # Create a label
    label = lv.label(lv.screen_active())
    label.set_text("Hello animations!")
    label.set_pos(100, 10)
    
    # Create a switch
    sw = lv.switch(lv.screen_active())
    sw.center()
    sw.add_state(lv.STATE.CHECKED)
    sw.add_event_cb(sw_event_cb, lv.EVENT.VALUE_CHANGED, label)

lv_example_anim_1()

Hello!

The animation callback has 2 parameters:

  1. lv.anim_t object instance (and not the target object what you set in a.set_var(label))
  2. animation value

See:

Usage example (in C):

So, fix is:

def anim_x_cb(anim, value):
    obj = anim.get_user_data()
    obj.set_x(value)

Thanks for your response, it helped me to make it work, but I still required some “tricks”:

  1. anim.get_user_data() returns a ¿¿Blob?? object wich dont have set_x method
  2. sw.add_event_cb crashes if I pass label as user_data
label = None

def anim_x_cb(anim, value):
    global label
    obj = anim.get_user_data()
    # use global label cause anim.get_user_data() returns Blob object wich dont have set_x() (maybe the label can be obtained from Blob.get_X, not sure)
    label.set_x(value)

def sw_event_cb(e):
    global label
    sw = e.get_target_obj()
    # Cant be used as the callback sets user_data as None
    #label = e.get_user_data()
    
    if sw.has_state(lv.STATE.CHECKED):
        a = lv.anim_t()
        a.init()
        a.set_var(label)
        a.set_values(label.get_x(), 100)
        a.set_duration(500)
        a.set_custom_exec_cb(anim_x_cb)
        a.set_path_cb(lv.anim_t.path_overshoot)
        a.start()
    else:
        a = lv.anim_t()
        a.init()
        a.set_var(label)
        a.set_values(label.get_x(), -label.get_width())
        a.set_duration(500)
        a.set_custom_exec_cb(anim_x_cb)
        a.set_path_cb(lv.anim_t.path_ease_in)
        a.start()

def lv_example_anim_1():
    global label
    label = lv.label(lv.screen_active())
    label.set_text("Hello animations!")
    label.set_pos(100, 10)
    sw = lv.switch(lv.screen_active())
    sw.center()
    sw.add_state(lv.STATE.CHECKED)
    # Crash if I pass label as user_data
    sw.add_event_cb(sw_event_cb, lv.EVENT.VALUE_CHANGED, None)

lv_example_anim_1()

Is there any set of tests or examples that the lv_micropython port should pass? maybe I can read them before build my code.