Using a Class member function as a callback function in FLTK.

1,287 views
Skip to first unread message

dmnan

unread,
Mar 31, 2015, 7:35:51 AM3/31/15
to fltkg...@googlegroups.com

I am trying to use a Class member function as a callback function.  Function pointers for member functions are relatively straight forward but using it as a callback function in FLTK is proving difficult.  I have probably misinterpreted something. 

In my class derived from Fl_Box, called 'mybox', I have placed a callback function 'callback_function' of which I will call when the 'button' is pressed.   That button press will subsequently change the color of 'mybox'.  Everything works fine up until I try to use the mybox::callback_function as a callback function in FLTK. 

Not sure how to implement this?   Any clues?
Code below. 

Thanks







#include <iostream>


#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>




using namespace std;


class mybox: public Fl_Box
{
   
public:
    mybox
(int x, int y, int w, int h): Fl_Box(x,y,w,h){}


   
void callback_function(Fl_Widget* wid,void* data)
   
{
       
if(this->color()==6)
       
{
           
this->color(3);
       
}
       
else if(this->color() == 3)
       
{
           
this->color(6);
       
}
   
}
};








int main(int argc, char **argv)
{


Fl_Window *mywindow = new Fl_Window(500,500,"MyWindow");


mybox
*bx = new mybox(20,20,400,400);
bx
->box(FL_PLASTIC_DOWN_BOX);
bx
->color(6);


// create a function pointer to record the location of callback_function inside mybox class.
void (mybox::*funct_pointer)(Fl_Widget* wid,void* data) = &mybox::callback_function;


//using the instance of mybox bx, call the function to TEST implementation.


//(bx->*funct_pointer)(0,0); // this call to the callback member function //'callback_function'
//changes the box to yellow.  Just a TEST.


Fl_Button *button = new Fl_Button(100,100,150,100,"Press to \n Change Color");
button
->color(14);
button
->box(FL_PLASTIC_UP_BOX);


// now add the callback to the class function 'callback_function
//this is where the problems start. I am not sure how to implement this.
// I have also tried using the below syntax.
//Fl_Callback *cback = bx->funct_pointer;
//then adding it as a callback function like this
// button->callback(cback);  // I also get errors but I'm sure I'm doing it wrong.

button
->callback(bx->*funct_pointer);


 mywindow
->show(argc, argv);
 
return Fl::run();
}


Martin McDonough

unread,
Mar 31, 2015, 7:39:09 AM3/31/15
to fltkg...@googlegroups.com
You can only use static methods for callbacks like that. Since all you have is a member and no object, it cannot be called with a valid object. As such, the `this' pointer will not be valid.

I commonly use a static method and pass the object in as the extra argument for FLTK, then cast it back to the correct type inside the callback.

Albrecht Schlosser

unread,
Mar 31, 2015, 7:56:21 AM3/31/15
to fltkg...@googlegroups.com
Hmm, maybe nitpicking, but to be precise (and maybe I misunderstood what
you wanted to say):

The widget that "calls" the callback is always available in the first
argument of the callback, hence there is no need to use that widget in
the extra argument. The extra argument (userdata) is free for any
additional information the callback may need.

Everything else has already been said here or elsewhere in this thread.

dmnan

unread,
Mar 31, 2015, 9:27:05 AM3/31/15
to fltkg...@googlegroups.com, albrech...@online.de

Put simply, what I want to determine is what to put here.
button->callback(??????, userdata).

Where I have ????? I don't know what to put there. The userdata part is simple. 

I'm trying to allocate my mybox::callback_function to 'button' as a callback function.  This is almost certainly possible but I'm unsure how.

You don't have to use static methods for callback functions.  But,, with FLTK that might be different. This is where I'm getting stuck :)

dmnan

unread,
Mar 31, 2015, 9:42:52 AM3/31/15
to fltkg...@googlegroups.com, albrech...@online.de
I should also add that in this case I'm using a function pointer to a class member function in place of the actual callback functions name.  

for example. 
When I would normally write this.

// when using a global function as a callback function. (the normal situation).
button->callback(normal_callback_function);



I want to use this: (I'm just not sure how to refer to the class::callback_function?)

button->callback(class::callback_function);

// because callback_function is a member of class.

Greg Ercolano

unread,
Mar 31, 2015, 9:57:21 AM3/31/15
to fltkg...@googlegroups.com
On 03/31/15 06:27, dmnan wrote:

Put simply, what I want to determine is what to put here.
button->callback(??????, userdata).
Where I have ????? I don't know what to put there. The userdata part is simple.

    That'd be a function pointer to your /static/ method.
    The typical pattern is:


class MyClass .. {

    // NORMAL CALLBACK METHOD
    void Button_CB2(Fl_Widget *w) {
      ..your code here can access other members/methods of the class..
    }

    // STATIC CALLBACK METHOD
    static void Button_CB(Fl_Widget *w, void *data) {
        MyClass *o = (MyClass*)data;
        o->Button_CB2(w);
    }

public:
    MyClass(..) {
        Fl_Button *b = new Fl_Button(..);
        b->callback(Button_CB, (void*)this);
    }
};


    This seemingly redundant pattern of calling a method that calls a method
    is actually necessary because we need to help C++ get the context of the class
    when no context exists. Note in the callback() setup code, we pass both the pointer
    to the /static/ callback method and a pointer to the class. The static method then
    is able to put the two together and invoke the real (non static) member function
    so that it has the class instance context setup, so that it can access the members
    and methods of that class instance.

    If that doesn't make sense, just do it anyway ;) Just know that there is a difference
    between static and non-static methods; read up on their differences in a good C++ book.

    Since you're probably new to FLTK, I suggest going to this fltk videos page
    and watching the "Beginners Guide To Programming FLTK", and the
    "Introduction To Using Fluid" after that.

    Those two videos cover callbacks, static members, and will introduce
    other things you may encounter as you ramp up with FLTK. They're a bit
    old, but still relevant.

dmnan

unread,
Apr 1, 2015, 10:28:42 AM4/1/15
to fltkg...@googlegroups.com, erco_...@seriss.com

Thanks.. I think you're right too. 
After some meaningful thought I think I will have to use a static function after all. .  
Reply all
Reply to author
Forward
0 new messages