Home > Enterprise >  C FLTK How to redraw a box from inside an timerfunction
C FLTK How to redraw a box from inside an timerfunction

Time:01-11

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

  •  Tags:  
  • Related