I finally used for the example: let btn_event_cb = block: var cnt = 0 (proc (e:ptr lv_event_t) {.cdecl.} = let code = lv_event_get_code(e) let btn = cast[ptr lv_obj_t](lv_event_get_target(e)) if code == LV_EVENT_CLICKED: echo now().utc, " clicked" cnt += 1 # Get the first child of the button which is the label and change its text*/ let label = lv_obj_get_child(btn, 0) lv_label_set_text_fmt(label, "Button: %d", cnt) ) Run
which works. It seems to store `cnt` globally, but I don't know well how to interpret the C generated code: ... N_LIB_PRIVATE NI cnt__ex485195button_4 = ((NI) 0); ... Run I have to try to create that variable as user data. In [this thread](https://forum.lvgl.io/t/user-data-context-for-event-callbacks/1177) they suggest using `lv_obj_set_user_data`. The issue was the loop at the bottom: while true: ## Periodically call the lv_task handler. ## It could be done in a timer interrupt or an OS task too. discard lv_timer_handler() # sleep(5 * 1000) #<--- this was too big sleep(5 * 10) Run I understand that the library was unable to catch the clicks due to this.