How can I unbind an event handler which I've bind as shown below?
MyFrame::MyFrame()
{
Bind(wxEVT_COMMAND_MENU_SELECTED,
[](wxCommandEvent&) {
// Do something useful
},
wxID_EXIT);
}
Many thanks for the first answer. I've added some additional information.
The possibility to unbind an event handler by using a concrete Functor is documented and works fine, but if you use the C++ 11 lambda style to bind somthing, later there is no Functor availibale to call the unbind method. And this causes trouble if the corresponding wxEvtHandler should by destroied.
Is there a "trick". . . if not I don't see a real use case to bind by using lambda functors. Hopefully I'm wrong . . .
Many thanks
Hacki
wxWidget's documentation specifies the exact way Unbind works for functors (and lambdas as well):
Currently functors are compared by their address which, unfortunately, doesn't work correctly if the same address is reused for two different functor objects.
So, if you want to Unbind some functor reliably, you should save the functor in a special place which is shared by Bind and Unbind call sites, and then pass the exact same object to both functions (they take const-references despite documentation not reflecting it).
This applies both to lambdas and functors, so it's not even C++11-specific. If you want to Unbind something, this something should have a fixed address in memory. Consequently, it should have a name. That somewhat kills the beauty of lambdas.
So, this should work:
static auto event_handler = [](wxCommandEvent&) {
// Do something
};
// ...
Bind(..., event_handler, ...);
// ...
Unbind(..., event_handler, ...);
But even this does not (or does, depending on your luck with location of temporary variables):
struct EventHandler {
void operator()(wxCommandEvent&) const {
// Do something
}
};
// ...
Bind(..., EventHandler(), ...);
// ...
Unbind(..., EventHandler(), ...);
Unfortunately there is no way to do this currently, you will need to store your lambda in an object to give it an identity, e.g.
auto const handler = [](wxCommandEvent&) { ... };
// To bind it:
Bind(wxEVT_MENU, handler, wxID_EXIT);
// To unbind it:
Unbind(wxEVT_MENU, handler, wxID_EXIT);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With