lvgl / lv_binding_micropython

LVGL binding for MicroPython
MIT License
237 stars 157 forks source link

problem with close_event_cb #100

Closed uraich closed 3 years ago

uraich commented 3 years ago

I try to add a close_event_cb to a button on my window:

Add control button to the header

close_btn = win.add_btn_right(lv.SYMBOL.CLOSE) # Add close button and use built-in close action close_btn.set_event_cb(lv.win.close_event_cb)

When pressing the button I get: TypeError: argument should be a 'win' not a 'obj'

amirgon commented 3 years ago

Hi @uraich !

The problem is that close_event_cb C API does not follow the conventions.

See lv_win.h:

void lv_win_close_event_cb(lv_obj_t * btn, lv_event_t event);

As you can see lv_win_close_event_cb pretends to be a member of win (it starts with lv_win_), but its first argument is lv_obj_t * btn and not win.

We expect a member function of an object to receive the object as their first argument (win in this case) and not some other object (btn in this case).
The Micropython binding script does not have a way to guess that in this case the lv_obj_t argument is supposed to be a btn and not a win.

I've mentioned this problem in https://github.com/lvgl/lvgl/issues/1763, hopefully it would be fixed on v8.


To work around this on v7 you have two options:

uraich commented 3 years ago

Hi Amir, Your first solution works if close_win_cb is a nested function. Otherwise I get an error than win is not bound. The second solution must read: close_btn.set_event_cb(lambda obj,e: lv.win.close_event_cb(lv.win.cast(obj), e))