Page 1 of 1

Object attributes and events

Posted: Sat Mar 03, 2012 3:08 pm
by denarced
The problem was that I was connecting a button clicked event with the button itself.
When I did that, the boost::weak_ptr attribute was messed up.
Why does it matter will I connect to the button or to the object which holds the weak_ptr?
The code should illustrate. I have commented out the problematic event connecting.

Code: Select all

class App : public wxApp
{
public:                     
    virtual bool OnInit();
    virtual int OnExit();                        
    void buttonClicked(wxCommandEvent& event);
    // stuff to initiate the weak_ptr
                           
private:                 
    boost::weak_ptr<MailBox> mailBox;
};

bool App::OnInit()
{
	// Stuff
	// button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(App::buttonClicked));
	Connect(button->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(App::buttonClicked));
}

void App::buttonClicked(wxCommandEvent& event)
{
	shared_ptr<MailBox> mail(this->mailBox.lock());
	if (mail) {
		// will never happen when button->Connect used
	}
}


Re: Object attributes and events

Posted: Sat Mar 03, 2012 3:44 pm
by JimFairway
Hi,

I think you want:

Code: Select all

button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(App::buttonClicked),NULL,this);
That tells the button to send its event to the wxApp object.

Hope that helps,

Jim

Re: Object attributes and events

Posted: Sat Mar 03, 2012 4:51 pm
by denarced
JimFairway wrote:Hi,

I think you want:

Code: Select all

button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(App::buttonClicked),NULL,this);
That tells the button to send its event to the wxApp object.

Hope that helps,

Jim
Hmm .. thanks for the advice. I believe your way is exactly the same as mine, just formulated in a different way.
And just in case you misunderstood me, my code does work. All I want to know is why it didn't work before :)

Re: Object attributes and events

Posted: Sat Mar 03, 2012 7:08 pm
by PB
denarced wrote: All I want to know is why it didn't work before :)
I believe this recent thread, although its topic title might look unrelated, dealt with the same issue. You might want to read it to avoid this common problem in the future (my two answers there in particular).

Re: Object attributes and events

Posted: Sat Mar 03, 2012 8:04 pm
by JimFairway
Hi,

If you're asking why this didn't work:

Code: Select all

button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(App::buttonClicked));
It's different from the code I posted in that you don't specify which object is the sink object for the event. So it defaults to the button itself
see:
http://docs.wxwidgets.org/stable/wx_wxe ... lerconnect

Given that you want your App object to handle the event on behalf of the button, specifying ",NULL, this);" will allow your App object to be defined as the sink object. Otherwise it will call your event handler method in App (App::buttonClicked), but this will point to the button object and not the App object.

Hope that's clear.

Jim

Re: Object attributes and events

Posted: Sun Mar 04, 2012 4:10 am
by denarced
Thank you PB and JimFairway!

The part about event sinks is simple enough and easy to remember.
I just didn't consider the possibility that when you define an event
handler, it'll execute the method in question in another object
entirely! Didn't know that was even possible because to my under-
standing, you'd have to create the object again and not copy with
a shallow copy operation either. Either a deep copy or just a plain
new object..

Re: Object attributes and events

Posted: Sun Mar 04, 2012 10:14 am
by PB
There's no copying at all going on. Both wxApp and wxButton inherit from wxEventHandler, the event sink is the original this used in Connect method (so in your case the caller's this). What you originally wrote is actually syntactically correct, and it may somewhat work as long as it doesn't do something wxEventHandler can not do, but it is usually not what one wants.

Connect method is unfortunately rather error prone, the mistake you made is a common one, so Connect was kind of deprecated for wxWidgets 2.9 (aka wxWidgets 3) and replaced with Bind.