Is this way to communicate between thread correct?

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
HansLjy
Earned a small fee
Earned a small fee
Posts: 19
Joined: Fri May 21, 2021 6:44 am

Is this way to communicate between thread correct?

Post by HansLjy »

In the controller I have a event handler

Code: Select all

void PageController::OnJoinSuccess(wxThreadEvent& event) {
	std::cerr << "Join Success" << std::endl;
}
In another thread I have:

Code: Select all

wxThreadEvent join_success(wxEVT_COMMAND_THREAD, eventID_join_success);
wxTheApp->QueueEvent(join_success.Clone());
std::cerr << "Join Success" << std::endl;
where eventID_join_success is a constant

I bind the handler in the following way:

Code: Select all

EVT_THREAD(eventID_join_success, PageController::OnJoinSuccess)
Then I found that after the first 'Join Success', nothing happens, namely the event has been queued but there is no response. What's wrong about this?
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Is this way to communicate between thread correct?

Post by doublemax »

Code: Select all

wxTheApp->QueueEvent(join_success.Clone());
This would only work if you're catching the event at wxApp level. Events never travel downwards in the window hierarchy. And only events that derive from wxCommandEvent bubble upwards in the window hierarchy.

A wxThreadEvent must be sent to the exact object where you want to handle it.
Use the source, Luke!
HansLjy
Earned a small fee
Earned a small fee
Posts: 19
Joined: Fri May 21, 2021 6:44 am

Re: Is this way to communicate between thread correct?

Post by HansLjy »

doublemax wrote: Sun Jun 27, 2021 10:21 am

Code: Select all

wxTheApp->QueueEvent(join_success.Clone());
This would only work if you're catching the event at wxApp level. Events never travel downwards in the window hierarchy. And only events that derive from wxCommandEvent bubble upwards in the window hierarchy.

A wxThreadEvent must be sent to the exact object where you want to handle it.
Does this mean I have to use wxCommandEvent? Then I change into this:

The handler:

Code: Select all

void PageController::OnJoinSuccess(wxCommandEvent& event) {
	std::cerr << "Join Success" << std::endl;
}
In the thread:

Code: Select all

wxCommandEvent join_success(JoinSuccessEvent, eventID_join_success);
wxTheApp->QueueEvent(join_success.Clone());
std::cerr << "Join Success" << std::endl;
In the header of an auxiliary file(I name it 'events.h')

Code: Select all

wxDECLARE_EVENT(JoinSuccessEvent, wxCommandEvent);
In 'events.cc'

Code: Select all

wxDEFINE_EVENT(JoinSuccessEvent, wxCommandEvent);
And I bind it like this:

Code: Select all

EVT_COMMAND(eventID_join_success, JoinSuccessEvent, PageController::OnJoinSuccess)
Seems this won't work either.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Is this way to communicate between thread correct?

Post by doublemax »

Does this mean I have to use wxCommandEvent?
No that won't work either. They only bubble upwards, e.g. from a wxButton to its parent, a wxPanel and its grandparent, a wxFrame. The never travel downwards (basically that would mean to check every single window in the application, which would be slow)

In your code, you must pass a pointer to a PageController instance to the thread, and send the event to it.
Use the source, Luke!
HansLjy
Earned a small fee
Earned a small fee
Posts: 19
Joined: Fri May 21, 2021 6:44 am

Re: Is this way to communicate between thread correct?

Post by HansLjy »

doublemax wrote: Sun Jun 27, 2021 11:00 am The never travel downwards (basically that would mean to check every single window in the application, which would be slow)
I see, but how do I send an event to it? Can I use QueueEvent of that component? Seems it's a private member?
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Is this way to communicate between thread correct?

Post by doublemax »

Code: Select all

SomeWindow->GetEventHandler()->QueueEvent(...)
Use the source, Luke!
jpo234
Experienced Solver
Experienced Solver
Posts: 70
Joined: Tue Feb 25, 2020 11:34 am

Re: Is this way to communicate between thread correct?

Post by jpo234 »

HansLjy wrote: Sun Jun 27, 2021 11:11 am
doublemax wrote: Sun Jun 27, 2021 11:00 am The never travel downwards (basically that would mean to check every single window in the application, which would be slow)
I see, but how do I send an event to it? Can I use QueueEvent of that component? Seems it's a private member?
I would use wxTheApp->CallAfter() with a suitable Lambda.

From https://docs.wxwidgets.org/3.0/classwx_ ... 3b8a0c6a12
Notice that it is safe to use CallAfter() from other, non-GUI, threads, but that the method will be always called in the main, GUI, thread context.
Post Reply