What MCU/Processor/Board and compiler are you using?
Atmel ARM32., arm-none-eabi-gcc.exe
What LVGL version are you using?
v7.7.2
What do you want to achieve?
I made a multi-tabbed screen. I like to put a temporary pop up container on top of it with buttons when I click on a text area. Inside the popup, I like to click a button in the popup to delete the container with the children buttons. The problem is that when I use lv_del_obj on the container of the buttons, I get a segmentation fault.
Q1) Why is there a segmentation fault?
Q2) What parent should I call with lv_cont_create: the tabbed view or lv_scr_act()?
Q3) What would the correct approach be to create and destroy this popup?
What have you tried so far?
I tried a simple lv_obj_clean on the parent container of the buttons. It erases all the buttons but leaves the parent container there.
I tried lv_obj_del_async(popupCont); and lv_obj_del(popupCont); which both give segmentation faults.
Code to reproduce
lv_obj_t * popupCont=NULL;
static void ta_event_cb(lv_obj_t* ta, lv_event_t e){
if (e == LV_EVENT_RELEASED) {
createPopup(lv_scr_act());
}
}
void createPopup(lv_obj_t* h) {
popupCont= lv_cont_create(h, NULL);
/*lv_obj_set_pos(popupCont, 10, 5);*/
lv_obj_set_pos(popupCont, 0, 0);
lv_obj_set_size(popupCont, 780, 160+35);
popupCont = lv_btn_create(popupCont, NULL);
lv_obj_set_event_cb(cancelBtn, popupCancelCb);
}
static void popupCancelCb(lv_obj_t* btn, lv_event_t e) {
if (e == LV_EVENT_SHORT_CLICKED || e == LV_EVENT_LONG_PRESSED_REPEAT) {
lv_obj_clean(popupCont);
lv_obj_del_async(popupCont);
}
}
I did not put tabbed in these code snippets. Could that make the difference? I have made a copy from my embedded code into CodeBlocks where I cloned just the codeblocks demo project today. I get the segmentation in both systems.
I noticed that the segmentation fault comes from the second time I create the popup and try to delete it. Could you please try again? Thanks
Your code as-is does not compile (cancelBtn does not exist), so I had to tweak it a bit. The tweaked version appears to be running fine. Can you please post a code sample which is self-contained and compiles correctly? The changes might be what hides it from me.
Hello,
My apologies for the code that did not compile. I will not rewrite my code and post without compiling again.
I found some causes of my error in the bigger program. I did 3 reparations.
I had some code outside of an if statement that filters out the kind of event in a callback. This code was acting on widgets that either did not exist yet or were destroyed by the lv_obj_del.
if (e == LV_EVENT_SHORT_CLICKED || e == LV_EVENT_LONG_PRESSED_REPEAT) {
2.Also, I made for sure that my container was deleted or created only once by A) setting the pointers to NULL after deletion and B) checking against NULL before creating.
I think I have some confusion about the event types and which one is the best for me The events LV_EVENT_RELEASED and LV_EVENT_SHORT_CLICKED are not the same. I just had them in my code without paying attention of the difference. On the embedded device, I am not sure how many multiple events are fired when I press on the touch screen. I will read up on them some more.
For completeness sake, I post code to the above questions that does compile. There are no run functionality errors. Many thanks to those who helped out.
lv_obj_t * popupCont=NULL;
static void popupCancelCb(lv_obj_t* btn, lv_event_t e) {
if (e == LV_EVENT_SHORT_CLICKED || e == LV_EVENT_LONG_PRESSED_REPEAT) {
lv_obj_clean(popupCont);
lv_obj_del_async(popupCont);
}
}
void createPopup(lv_obj_t* h) {
popupCont= lv_cont_create(h, NULL);
lv_obj_set_pos(popupCont, 0, 0);
lv_obj_set_size(popupCont, 300, 300);
lv_obj_t* cancelBtn = lv_btn_create(popupCont, NULL);
lv_obj_t* label = lv_label_create(cancelBtn, NULL);
lv_label_set_text(label, "cancel");
lv_obj_set_event_cb(cancelBtn, popupCancelCb);
}
static void ta_event_cb(lv_obj_t* ta, lv_event_t e){
if (e == LV_EVENT_RELEASED) {
createPopup(lv_scr_act());
}
}
/**********************
* GLOBAL FUNCTIONS
**********************/
#if WIN32
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
#else
int main(int argc, char** argv)
#endif // WIN32
{
/*Initialize LittlevGL*/
lv_init();
/*Initialize the HAL for LittlevGL*/
hal_init();
/*Check the themes too*/
lv_disp_set_default(lv_windows_disp);
lv_obj_t* ta0 = lv_textarea_create(lv_scr_act(), NULL);
lv_textarea_set_text(ta0, "open the popup");
lv_obj_set_event_cb(ta0, ta_event_cb);
createPopup(lv_scr_act());
/*Run the v7 demo*/
/*lv_demo_widgets();*/
#if WIN32
while(!lv_win_exit_flag) {
#else
while(1) {
#endif // WIN32
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
lv_task_handler();
usleep(1000); /*Just to let the system breath*/
}
return 0;
}
LV_EVENT_RELEASED fires whenever you release the object, whereas LV_EVENT_SHORT_CLICKED only fires if the object hasn’t been held down long enough to qualify as a “long press”.