wxThread wait replacement

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.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxThread wait replacement

Post by doublemax »

wxJack wrote: Fri May 10, 2019 3:40 pm @doublemax
You mean: call from the menu of your bigger project a wxFrame and not a wxDialog (actually it was a wxWindow but I improperly called the class using the word dialog).
Did I understand?
I want to put this dialog inside a bigger project.
I'm talking about this dialog. It way my understanding that this dialog is a component that contains the thread code and that should be re-used in another project. This dialog should be a wxFrame instead. And be shown with Show() and not ShowModal().
Use the source, Luke!
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: wxThread wait replacement

Post by alys666 »

ONEEYEMAN wrote: Fri May 10, 2019 3:58 pm The code will execute this code fast in order to not block the GUI thread.
Or if the calculation take place longer than 50 seconds:

Code: Select all

void MyFrame::OnButtonClick(wxCommandEvent &event)
{
     wxBeginBusyCursor();
     // perform some calculation
     // update the data in other controls
     wxEndBusyCursor();
}
What is wrong with those approach?

Keep in mind - the event handler will be executed very fast, in order not to block the GUI. So unless the calculation is executed longer than ~50 seconds (keep in mind that human eye is much more sensitive than 50 seconds) I wouldn't bother with the MT.

Thank you.
event handler(as any code) must be executed by some thread. imho, in wxWidgets it's the gui thread(or some special internal thread or worker). so it will be blocked, because will "perform some calculation". this will block events handling and possibly controls repaint.
Last edited by alys666 on Fri May 10, 2019 8:49 pm, edited 1 time in total.
ubuntu 20.04, wxWidgets 3.2.1
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: wxThread wait replacement

Post by alys666 »

doublemax wrote: Fri May 10, 2019 1:07 pm I'm still not quite sure why you want to replace Wait() or with what. If that's the behavior you want, why don't you just use joinable threads and Wait() till they're done? With Wait(wxTHREAD_WAIT_YIELD) GUI updates should still work. (I've never done this though, so i can only rely on the documenation).
i used wxYield() in my last code, but sometimes(kinda every half hour) it issued runtime error, a kind of - "recursive Yield".
imho wait with yield could have the same problem.
can be completely cured only if the gui thread works only with short user code and handlers(without trying to Yield()), and all long work has been doing in user threads with sending wxMessages to gui thread.
ubuntu 20.04, wxWidgets 3.2.1
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxThread wait replacement

Post by doublemax »

I think the "wait logic" needs to be moved to the thread.

Similar to the code you posted earlier, it should look like this:

Code: Select all

wxThread::Entry()
{
  if( method == 1 )
  {
    foo1()
    foo4()
  }
  else if( method == 2 )
  {
    foo4()
    foo1()
  }
}
If you need more than 2 or more complicated cases, there are more elegant solutions, but in general, that's how i would do it.
Use the source, Luke!
wxJack
Experienced Solver
Experienced Solver
Posts: 83
Joined: Wed Jun 20, 2018 8:06 am

Re: wxThread wait replacement

Post by wxJack »

@ONEEYEMAN

Thank you! I don't use wxBusyCursor in order for me to be able to stop the operations if I want.
But why? You are not spewing data from some secondary device, right?
I perform some long calculations and copy some files from a folder A to a folder B.
Or if the calculation take place longer than 50 seconds:
You mean 50 ms ?
Anyway, sometimes the entire operation takes several minutes.
Thank you very much!

@doublemax
It way my understanding that this dialog is a component that contains the thread code and that should be re-used in another project. This dialog should be a wxFrame instead. And be shown with Show() and not ShowModal().
Yes you're right. This component contains its own GUI/main thread with some buttons, a wxListCtrl, some checkbox...And contains also some
secondary threads that perform some operations and update the GUI by means of events. The GUI remains responsive (for example I can interrupt the operations with a Stop button).
If you need more than 2 or more complicated cases, there are more elegant solutions, but in general, that's how i would do it.
Yes, I do. Maybe I have to rearrange everything (but I will try with the suggestion about the wxFrame first!).
The following code could be a great idea, I just need to think about the smartest way to do it.

Code: Select all

wxThread::Entry()
{
  if( method == 1 )
  {
    foo1()
    foo4()
  }
  else if( method == 2 )
  {
    foo4()
    foo1()
  }
}
The strange thing is: the bigger project has its own GUI. My dialog has its own GUI. Why using the second dialog working in background blocks the gui of the bigger project? Is it because of this? -->
This dialog should be a wxFrame instead.
To have a better understading of the topic: the dialog shares the same queue of events of the window it is called from and the wxFrame doesnt?
Just to be sure I get your point. I'm going to look at this inside the documentation.

Thank you a lot guys.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxThread wait replacement

Post by doublemax »

Why using the second dialog working in background blocks the gui of the bigger project?
It's the nature of modal dialogs that you can't use any controls of the underlying window of the same application. Just with a fileselector dialog, if you click outside, you just hear a ping, but you can't click on any button etc. This has nothing to do with the worker threads.

The event loop of the underlying window is still active though, e.g. if it had an animation contolled by a timer, that would still work.
Use the source, Luke!
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: wxThread wait replacement

Post by alys666 »

good reading about dialog modality and nonmodality - https://www.nngroup.com/articles/modal-nonmodal-dialog/
technically, modal dialog grabs all user input events(mouse, keyboard) and handles it, if can. if cannot - system beeps, or something.
if nonmodal dialog cannot handle user event - system propagates it to another windows.
ubuntu 20.04, wxWidgets 3.2.1
wxJack
Experienced Solver
Experienced Solver
Posts: 83
Joined: Wed Jun 20, 2018 8:06 am

Re: wxThread wait replacement

Post by wxJack »

It's the nature of modal dialogs that you can't use any controls of the underlying window of the same application. Just with a fileselector dialog, if you click outside, you just hear a ping, but you can't click on any button etc. This has nothing to do with the worker threads.

The event loop of the underlying window is still active though, e.g. if it had an animation contolled by a timer, that would still work.
Ooh only now I totally understand! I misunderstood. The 2nd window that is open from the main one is not a modal dialog (no pings if I click
on the 1st one while the second one is working "in background"). The fact is that I actually can click a button of the 1st interface (the main one from which I can open the second one) while the 2nd one has already been opened, but its output is shown only after the end of the background work of the 2nd window (if the operations of the 2nd one have been activated as first). From here my doubt is: do these 2 interfaces share a queue of events?
Thank you very much.
good reading about dialog modality and nonmodality - https://www.nngroup.com/articles/modal-nonmodal-dialog/
technically, modal dialog grabs all user input events(mouse, keyboard) and handles it, if can. if cannot - system beeps, or something.
if nonmodal dialog cannot handle user event - system propagates it to another windows.
very useful reading, than you very much! Now I avoid misunderstandings between modal and nonmodal dialogs!
A modal dialog always blocks at ShowModal(), that has nothing to do with the threads. Try using a wxFrame instead.
So my 1st attempt tomorrow as soon as I come back at the university, I will try using a wxFrame instead of a wxWindow and I will see how my window
has been integrated (I'm not the one who handled the integration part of this project).
Keep you posted.
Thank you
Post Reply