Implementing a progress bar class

I learn C ++ using the book Principles and Practices for Programming Using C ++ . Chapter 16 describes methods that use the gui part of the FLTK library through the interface library.

One of the exercises in this chapter is to animate the movement of the image, controlled by the start and stop button implemented in the classroom. For synchronization, I found that using FLTKs Fl::add_timeout and Fl::repeat_timeout is a better solution than going into an infinite loop and using Sleep (), blocking other callbacks.

I was unable to implement a working solution using Fl::add_timeout and Fl::repeat_timeout , but here I found an example using the progress bar with a start and stop button:

 #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Progress.H> #include <FL/Fl_Button.H> Fl_Progress* progBar; void runcount(void*) { if (progBar->value() == progBar->maximum()) { Fl::remove_timeout(runcount); progBar->value(0); } else { Fl::repeat_timeout(1, runcount); progBar->value(progBar->value() + 1); } } void cb_startb(void) { Fl::add_timeout(1, runcount); } void cb_stopb(void) { Fl::remove_timeout(runcount); } int main (int argc, char *argv[]) { Fl_Double_Window window(200,70,"ProgressBar Test"); progBar = new Fl_Progress(5, 10, window.w()-10, 20); progBar->box(FL_SHADOW_BOX); progBar->selection_color((Fl_Color)4); progBar->minimum(0); progBar->maximum(10); Fl_Button* start_button = new Fl_Button(10, 40, 80, 20, "START"); start_button->box(FL_SHADOW_BOX); start_button->callback((Fl_Callback*)cb_startb,(void*)"start"); Fl_Button* stop_button = new Fl_Button(110, 40, 80, 20, "STOP"); stop_button->box(FL_SHADOW_BOX); stop_button->callback((Fl_Callback*)cb_stopb,(void*)"stop"); window.end(); window.show(argc, argv); return Fl::run(); } 

This example compiles and works fine.

Then I tried to give an example of execution in a class, and this is where I got stuck.

 #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Progress.H> #include <FL/Fl_Button.H> #include <string> class ProgressBar : public Fl_Double_Window { public: ProgressBar(int w, int h, const std::string label) : Fl_Double_Window{ w,h,label.c_str() } { progBar = new Fl_Progress(5, 10, 10, 20); progBar->box(FL_SHADOW_BOX); progBar->selection_color((Fl_Color)4); progBar->minimum(0); // set range: 0-10 progBar->maximum(10); start_button = new Fl_Button(10, 40, 80, 20, "START"); start_button->box(FL_SHADOW_BOX); start_button->callback((Fl_Callback*)cb_startb, (void*)"start"); //compile error: 'type-cast':cannot convert //from 'overloaded-function'.. stop_button = new Fl_Button(110, 40, 80, 20, "STOP"); stop_button->box(FL_SHADOW_BOX); stop_button->callback(static_cast<Fl_Callback*>(cb_stopb), (void*)"stop");//(Fl_Callback*)cb_stopb //compile error: 'type-cast':cannot convert from 'overloaded-function'.. } ~ProgressBar() { delete progBar; delete start_button; delete stop_button; } private: void runcount(void*) { if (progBar->value() == progBar->maximum()) // max reached, stop timer and reset pregress bar to 0 { Fl::remove_timeout(runcount); // non-standard syntax, use & to create a pointer to member progBar->value(0); } else // timer running, recursive calling this function - increase progress bar by 1. { Fl::repeat_timeout(0.1, runcount); ///compile error: non-standard syntax, use & to create a pointer to member progBar->value(progBar->value() + 1); } } void cb_startb(void) { Fl::add_timeout(1, runcount);///compile error: non-standard syntax, use & to create a pointer to member } void cb_stopb(void) { Fl::remove_timeout(runcount);///compile error: non-standard syntax, use & to create a pointer to member } Fl_Button* start_button; Fl_Button* stop_button; Fl_Progress* progBar; }; int main() { ProgressBar* progBar = new ProgressBar{200, 700,"Progress bar" }; progBar->end(); progBar->show(); return Fl::run(); delete progBar; } 

I cannot find out how to implement callback functions. I get compilation errors as written in the comments.

If I runcount() old function runcount() , the compilation error with 4 calls to runcount() disappears, but it makes no sense for me to make this function static. I get new errors when calling progBar.

How can I implement this class to use the start and stop function?

I probably lack some knowledge about how the callback function and using pointers work, so I'm trying to work this out.

+6
source share
1 answer

The callback has a signature

 void xxx(Fl_Widget*, void*) 

ProgressBar callbacks have a signature

 void ProgressBar::xxx(void*) 

A simple solution to this problem is to create a static function, which in turn calls a member function. Using cb_startb as an example

 // Where you are getting the compilation error start_button->callback(_cb_startb, this); ... // Create a static version of your function static void _cb_startb(Fl_Widget*, void* self) { reinterpret_cast<ProgressBar*>(self)->cb_startb(); } // This is the member function void cb_startb() { // do the same thing for runcount Fl::add_timeout(1, _runcount, this); } 

If you apply this model to runcount, cb_startb and cb_stopb, it should get rid of most of your compilation errors. Wherever you use runcount as a parameter, switch to the static version using this as the void * parameter.

Minor note: change the label in the constructor to const std :: string &,

+1
source

Source: https://habr.com/ru/post/1015268/


All Articles