Using Bind in derived classes

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
jwcnmr
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Apr 20, 2022 4:58 pm

Using Bind in derived classes

Post by jwcnmr »

In WxPython you can create an abstract base class where you can bind to an empty (abstract) method like this:

Code: Select all

class ComdButton(wx.Button):
    def __init__(self, panel, label):
        super().__init__(panel, label = label)
        self.Bind(wx.EVT_BUTTON, self.comd)

    # filled in later in derived classes
    def comd(self, e): pass
Then you can create derived button classes which are already bound to the filled in comd method, without using Bind in the derived class.

Code: Select all

class AddButton(ComdButton):
    def __init__(self, panel, med):
        super().__init__(panel, "Add")
        self.med = med

    # called by base class
    def comd(self, e):
        self.med.addClicked()
But I can't make this work in C++. My base class is called DButton and uses Bind in the same way:

Code: Select all

class DButton: public wxButton {

protected:
    Mediator* med;

public:
    DButton(wxPanel* panel, int id, const std::string label, Mediator* med, wxApp* app): 
         wxButton(panel, id, wxString::wxString(label), wxDefaultPosition,
            wxDefaultSize)
    {
        this->med = med;
        Bind(wxEVT_BUTTON, &DButton::comd, this);
    }
  
  //abstract method to be completed in derived classes 
    virtual void comd(wxCommandEvent& event) {}
     
};
Then the derived AddButton class is similar to the wxPython one:

Code: Select all

class AddButton : public DButton
{
public:
    AddButton(wxPanel* panel, int id, Mediator* med, wxApp* app) :
        DButton(panel, id, std::string("Add"), med, app)   {}

        void comd() {
            this->med->addClicked();
       }
    
};
The comd method on AddButton is never called on the button click. This may just be a silly error, but so far I haven't spotted it. Am I missing something?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Using Bind in derived classes

Post by PB »

jwcnmr wrote: Sat May 28, 2022 1:51 pm I can't make this work in C++. My base class is called DButton and uses Bind in the same way:

Code: Select all

class DButton: public wxButton {
  //abstract method to be completed in derived classes 
    virtual void comd(wxCommandEvent& event) {}
     
};
Then the derived AddButton class is similar to the wxPython one:

Code: Select all

class AddButton : public DButton
{
        void comd() {
            this->med->addClicked();
       }    
};
The comd method on AddButton is never called on the button click. This may just be a silly error, but so far I haven't spotted it. Am I missing something?
Yes, you missed that comd() in AddButton does not override comd from DButton. To override a method, the overridden method has to have the exactly some signature as the base one, just having the same name obviously cannot be enough (as there can be multiple methods with the same name but different signatures).

So, to fix this you need to change the signature of comd() in AddButton to match the one in DButton, i.e., add wxCommandEvent& parameter. C++ has "override" keyword one can use to avoid mistakes like this: The compiler would then tell you that the method is not actually overriding anything.

FWIW, IMO, your approach, i.e., to use a class of derived from wxButton like this, is usually a sign of doing something wrong, programming against the grain....
jwcnmr
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Apr 20, 2022 4:58 pm

Re: Using Bind in derived classes

Post by jwcnmr »

Thanks, I knew it would be something dumb. Since this is a good approach to the Command and Mediator Design Patterns, it may be unfamiliar, but not "something wrong."
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using Bind in derived classes

Post by ONEEYEMAN »

Hi,
Why do you even need to override this?
Just don't create the event handler.

Or it will be much better to not override the event handler. Instead create a virtual function in you base class and call it from the event handler.
Then you override this virtual and it will be called automatically.

Thank you.
Post Reply