How do I call a box.redraw from a routine? I have a timer callback from which I a have to assign a new picture to box1. My programm crashes at this point.
...
Fl_Window *win = NULL;
Fl_Box *box1 = NULL;
static void get_new_pic(void*) { // Timer callback
const char *filename = "pic2.png";
Fl_PNG_Image png(filename);
box1->image(png);
box1->redraw(); // this kicks the application
Fl::repeat_timeout(2,CB_Hole_Info);
}
int main() {
win = new Fl_Window(240,240); // make a window
box1 = new Fl_Box(0,0,240,180); // widget that will contain image
const char *filename = "pic1.png";
Fl_PNG_Image png(filename);
box1->image(png);
Fl::add_timeout(2, get_new_pic, buff); // setup a timer
win->show();
return(Fl::run());
}
Regards
CodePudding user response:
Your way of adding the image in the timeout is correct. However, you allocate the image on the stack: Fl_PNG_Image png(filename);, so when you leave the timer, the image is automatically deleted together with the stack. When the box is actually drawn, the image is not there anymore.
FLTK does not copy the image. It just links to it.
You'd have to write Fl_PNG_Image *png = new Fl_PNG_Image(filename); and fix the rest of the code to use a pointer and make sure that the image is deleted at the very end.
CodePudding user response:
Maybe I could add another question here. As Matthiás Melcher has shown above, this works:
static void get_new_pic(void*) { // Timer callback
Fl_PNG_Image *png2 = new Fl_PNG_Image("pic2.png");
box1->image(*png2);
box1->redraw();
Fl::repeat_timeout(2,CB_Hole_Info);
}
That was my initial problem. However, it should be able to choose between different images. The actual timer routine would then look something like this:
...
if (condition1) {
...
} else if (condition2) {
...
} ...
This would use new memory again each time. I have therefore tried the following approach:
Fl_Window *win = NULL;
Fl_Box *box1 = NULL;
Fl_PNG_Image *png1 = NULL;
Fl_PNG_Image *png2 = NULL;
static void get_new_pic(void*) { // Timer callback
if (condition1) {
box1 ->image(*png1);
box1 ->redraw();
} else if (condition2) {
box1 ->image(*png2);
box1 ->redraw();
}
Fl::repeat_timeout(2,get_new_pic);
}
int main() {
win = new Fl_Window(240,180);
box1 = new Fl_Box(0,0,240,179);
Fl_PNG_Image *png1 = new Fl_PNG_Image("pic1.png"); // define 1. pic
box1->image(png1); // shows 1. pic
Fl_PNG_Image *png2 = new Fl_PNG_Image("pic2.png"); // define 2. pic
Fl::add_timeout(2, get_new_pic); // setup a timer
win->show();
return(Fl::run());
}
It does not give an error, but no image is displayed within the timer-callbacks. Even the first image disappears if condition1 is true.
Regards
