Using Lambda expressions in addListener()

The syntax for adding listener to an ofxButton is generally as follows:

myButton.addListener( this , &ofApp::myButtonListener);

and then define myButtonListener() somewhere else in the file:

void ofApp::myButtonListener(){ ... }

This got me wondering if there is a way to utilise lambda expressions for the Listener method. This would be very useful especially when the listener method doesn’t do a lot.
I tried to write something like:

myButton.addListener( this , [this] (){
 *...handle the event...*
});

but it fails to compile, where ofAddListener() complains: No matching function for call to ‘ofAddListener’. Is there a way to do this?

Hi @fjason2713 I found an error in the link that @moebiussurfing posted, which I address further down.

ofxButton does not have a way for adding lambdas, but if you instead make your ofxGui with ofParameters you can.

I prefer to use ofParameters instead of directly instancing ofxGui elements, as I find it more flexible and easier.

so for a button you use an ofParameter<void> button; There is an example which shows how to deal with these, but is almost the same as using ofxButton, ofxSlider etc.

Now you can use the lambda as you mention.

In short, the lambda must have as argument a non-const reference of the type of the event you are listening to, so in the case of using ofParameters it is the type of the parameter. (the one you put inside the <>). The ofParameter<void> is a special case and you can omit the arguments passed to it.

@arturo
I think that there is an error in your blog post that @moebiussurfing mentions. In the last section that addresses lambdas and shows the following code, the lambda is missing the arguments

class MyClass{
private:
    ofEventListener listener;

public:
    MyClass(){
        listener = ofEvents().mousePressed.newListener([this]{
            std::cout << mouse.pos << std::endl;
        });
    }
}

it should be

class MyClass{
private:
    ofEventListener listener;

public:
    MyClass(){
        listener = ofEvents().mousePressed.newListener([this](ofMouseEventArgs&mouse){
            std::cout << mouse << std::endl;
        });
    }
}
1 Like