GUI responsive while threads working

Hi

How do I keep the GUI responsive while threads are working?

I have an wx.python app with a wx.Frame containing a Toolbar
a Statusbar and a GridBagSizer.
The cells of the grid bag contain matplotlib figures or
wx.lib.plot canvas to show plots.
These plots are updated by timers (threads).
So each plot generates a certain processing load.

As long as the processing load is low, the GUI (e.g. Toolbar)
is responsive.
When more plots are added, and the processing load increases,
the plots do still update, but the GUI does not respond at all.

How can I improve the situation?
Can I start a repeating timer to "activate" the GUI? (How)

Linux 2.6.22.19-0.1-default, Core2duo
Python 2.5.1
wx 2.8.9.2

Regards

···

--
Kurt Mueller

Hi!

···

On Dec 10, 10:12 am, Kurt Mueller <kurt.alfred.muel...@gmail.com> wrote:

Hi

How do I keep the GUI responsive while threads are working?

I have an wx.python app with a wx.Frame containing a Toolbar
a Statusbar and a GridBagSizer.
The cells of the grid bag contain matplotlib figures or
wx.lib.plot canvas to show plots.
These plots are updated by timers (threads).
So each plot generates a certain processing load.

As long as the processing load is low, the GUI (e.g. Toolbar)
is responsive.
When more plots are added, and the processing load increases,
the plots do still update, but the GUI does not respond at all.

How can I improve the situation?
Can I start a repeating timer to "activate" the GUI? (How)

Linux 2.6.22.19-0.1-default, Core2duo
Python 2.5.1
wx 2.8.9.2

Regards
--
Kurt Mueller

There are various suggestions on the wiki for this scenario:

http://wiki.wxpython.org/LongRunningTasks

Did you look at that?

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

Hi,

On Dec 10, 10:12 am, Kurt Mueller <kurt.alfred.muel...@gmail.com>

How do I keep the GUI responsive while threads are working?
I have an wx.python app with a wx.Frame containing a Toolbar
a Statusbar and a GridBagSizer.
The cells of the grid bag contain matplotlib figures or
wx.lib.plot canvas to show plots.
These plots are updated by timers (threads).
So each plot generates a certain processing load.
As long as the processing load is low, the GUI (e.g. Toolbar)
is responsive.
When more plots are added, and the processing load increases,
the plots do still update, but the GUI does not respond at all.
How can I improve the situation?
Can I start a repeating timer to "activate" the GUI? (How)
Linux 2.6.22.19-0.1-default, Core2duo
Python 2.5.1
wx 2.8.9.2

There are various suggestions on the wiki for this scenario:
LongRunningTasks - wxPyWiki
Did you look at that?

Yes. There are 3 approaches in the wiki:
The first approach is using worker threads.
-> I use threads, I use repeating timers to start the updates for the plots.
The second approach is with wx.Yield() which I do not understand.
The third approach is to start work with an Idle Event.

I think the problem in my application is, that many timers
start threads, they update the plots. If there is always one thread
running, the GUI never gets a chance to respond.

The other thing is, that an update for the plot takes about 0.1[s],
so it is not a "long running task".
If I start 10 update tasks every second, then there is always one thread
running.

How does threading behaves if there is always one thread ready for running,
and there is never an idle situation?

Regards

···

--
Kurt Mueller

Maybe DelayedResult [1] is what you're looking for. I tend to use it
for tasks that takes a little longer than usual (network, I/O, high
CPU load, etc..)

def producer():
  long_running_task()

def consumer(result):
  try: # just in case producer throws something
    r = result.get()
  except:
    # do whatever you wan to do
  else:
    # updates GUI....

DelayedResult.startWorker(consumer, producer)

Never, ever, call a wx method inside the producer function, let it to
be done inside the consumer.

[1] http://www.wxpython.org/docs/api/wx.lib.delayedresult-module.html

···

On Thu, Dec 10, 2009 at 1:12 PM, Kurt Mueller <kurt.alfred.mueller@gmail.com> wrote:

Hi

How do I keep the GUI responsive while threads are working?

Hi,

Hi,

> On Dec 10, 10:12 am, Kurt Mueller <kurt.alfred.muel...@gmail.com>
>> How do I keep the GUI responsive while threads are working?
>> I have an wx.python app with a wx.Frame containing a Toolbar
>> a Statusbar and a GridBagSizer.
>> The cells of the grid bag contain matplotlib figures or
>> wx.lib.plot canvas to show plots.
>> These plots are updated by timers (threads).
>> So each plot generates a certain processing load.
>> As long as the processing load is low, the GUI (e.g. Toolbar)
>> is responsive.
>> When more plots are added, and the processing load increases,
>> the plots do still update, but the GUI does not respond at all.
>> How can I improve the situation?
>> Can I start a repeating timer to "activate" the GUI? (How)
>> Linux 2.6.22.19-0.1-default, Core2duo
>> Python 2.5.1
>> wx 2.8.9.2
> There are various suggestions on the wiki for this scenario:
>LongRunningTasks - wxPyWiki
> Did you look at that?

Yes. There are 3 approaches in the wiki:
The first approach is using worker threads.
-> I use threads, I use repeating timers to start the updates for the plots.
The second approach is with wx.Yield() which I do not understand.
The third approach is to start work with an Idle Event.

I've never tried the 2nd or 3rd ones...I thought there was an example
using Queues too though...also something I haven't tried.

I think the problem in my application is, that many timers
start threads, they update the plots. If there is always one thread
running, the GUI never gets a chance to respond.

The other thing is, that an update for the plot takes about 0.1[s],
so it is not a "long running task".
If I start 10 update tasks every second, then there is always one thread
running.

How does threading behaves if there is always one thread ready for running,
and there is never an idle situation?

Regards
--
Kurt Mueller

I've never had any issues with running multiple threads in my
applications. Note that wxPython isn't thread-safe, so if you are
trying to update the GUI directly from a thread, you'll probably have
issues.

DON'T DO THIS:

# inside thread
myFrame.SetBackgroundColour()
myFrame.myTextCtrl.SetValue()

Instead, use wx.CallAfter, wx.CallLater or wx.PostEvent

Of course, if you are already doing that, then we'll probably need a
sample app:

See MakingSampleApps - wxPyWiki for more info.

···

On Dec 10, 12:05 pm, Kurt Mueller <kurt.alfred.muel...@gmail.com> wrote:

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

Hi,

Mike Driscoll:

I've never had any issues with running multiple threads in my
applications. Note that wxPython isn't thread-safe, so if you are
trying to update the GUI directly from a thread, you'll probably have
issues.
DON'T DO THIS:
# inside thread
myFrame.SetBackgroundColour()
myFrame.myTextCtrl.SetValue()
Instead, use wx.CallAfter, wx.CallLater or wx.PostEvent

Within the threads I collect some data,
make some numpy calculations, and
then I update the plot with the
wx.lib.plot.PlotCanvas.Draw() method.
Does that makes trouble?
I could call it with wx.CallAfter if this would help.

Of course, if you are already doing that, then we'll probably need a
sample app:
See MakingSampleApps - wxPyWiki for more info.

Jouh, I was afraid of that.
The app has about 5000 lines of code.
But...

Regards

···

--
Kurt Mueller

Gabriel Andrade:

Maybe DelayedResult [1] is what you're looking for. I tend to use it
for tasks that takes a little longer than usual (network, I/O, high
CPU load, etc..)
def producer():
long_running_task()
def consumer(result):
try: # just in case producer throws something
r = result.get()
except:
# do whatever you wan to do
else:
# updates GUI....
DelayedResult.startWorker(consumer, producer)
Never, ever, call a wx method inside the producer function, let it to
be done inside the consumer.
[1] http://www.wxpython.org/docs/api/wx.lib.delayedresult-module.html

Thanks Gabriel for the hint.
Maybe I was not careful in not calling any wx method in the threads.
I'll check that first.

But maybe only tomorrow because it is 09:00pm (21:00) here :slight_smile:

Regards

···

--
Kurt Mueller

This could be the issue. Try wrapping it in wx.CallAfter and see if it
helps.

···

On Dec 10, 1:45 pm, Kurt Mueller <kurt.alfred.muel...@gmail.com> wrote:

Hi,

Mike Driscoll:

> I've never had any issues with running multiple threads in my
> applications. Note that wxPython isn't thread-safe, so if you are
> trying to update the GUI directly from a thread, you'll probably have
> issues.
> DON'T DO THIS:
> # inside thread
> myFrame.SetBackgroundColour()
> myFrame.myTextCtrl.SetValue()
> Instead, use wx.CallAfter, wx.CallLater or wx.PostEvent

Within the threads I collect some data,
make some numpy calculations, and
then I update the plot with the
wx.lib.plot.PlotCanvas.Draw() method.
Does that makes trouble?
I could call it with wx.CallAfter if this would help.

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

Kurt Mueller wrote:

Within the threads I collect some data,

OK

make some numpy calculations,

OK

and then I update the plot with the
wx.lib.plot.PlotCanvas.Draw() method.
Does that makes trouble?

Probably, yes -- it's going to be making wx calls -- at least 1, anyway. if you are using wxAgg, then it is doing the drawing in its own code, to an agg buffer in memory, then copying that over to a wxBitmap and blitting it to the screen. Those past two steps are not thread-safe.

I don't know that there is a way to get MPL do do most of its drawing in a thread, then do the final blit separately -- it would take some poking into the wx back-end code, which is a bit messy.

you might try doing your calculations in a separate thread, then calling MPL from the main thread, and see how that works for you.

The other thing is, that an update for the plot takes about 0.1[s],
so it is not a "long running task".
If I start 10 update tasks every second, then there is always one thread
running.

How does threading behaves if there is always one thread ready for running,
and there is never an idle situation?

That should work -- the whole point of threads is that they run in parallel ,they are not waiting for an idle state, or one to finish before the next one starts. However, there is the issue of the global interpreter lock (GIL). In Python, if operations may not be thread safe, they ca lock the interpreter to assure that they don't et stomped on by another thread -- this is complicated, and I have no idea when it is invoked, but it does allow one thread to freeze of the interpreter in some situations -- maybe that's happening here, but I'd try the above first.

Of course, if you are already doing that, then we'll probably need a
sample app:
See MakingSampleApps - wxPyWiki for more info.

Jouh, I was afraid of that.
The app has about 5000 lines of code.
But...

you don't need all of it at all -- just make a simple app that does a bunch of MPL plotting and see what you get -- asking on the MPL list might be helpful too.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Kurt Mueller wrote:

Hi,

On Dec 10, 10:12 am, Kurt Mueller <kurt.alfred.muel...@gmail.com>
    

How do I keep the GUI responsive while threads are working?
I have an wx.python app with a wx.Frame containing a Toolbar
a Statusbar and a GridBagSizer.
The cells of the grid bag contain matplotlib figures or
wx.lib.plot canvas to show plots.
These plots are updated by timers (threads).
So each plot generates a certain processing load.
As long as the processing load is low, the GUI (e.g. Toolbar)
is responsive.
When more plots are added, and the processing load increases,
the plots do still update, but the GUI does not respond at all.
How can I improve the situation?
Can I start a repeating timer to "activate" the GUI? (How)
Linux 2.6.22.19-0.1-default, Core2duo
Python 2.5.1
wx 2.8.9.2
      

There are various suggestions on the wiki for this scenario:
LongRunningTasks - wxPyWiki
Did you look at that?
    
Yes. There are 3 approaches in the wiki:
The first approach is using worker threads.
-> I use threads, I use repeating timers to start the updates for the plots.
The second approach is with wx.Yield() which I do not understand.
The third approach is to start work with an Idle Event.

I think the problem in my application is, that many timers
start threads, they update the plots. If there is always one thread
running, the GUI never gets a chance to respond.

Just to be clear. You have multiple timers and with each timer start you create a thread that does all the calculations and updates the plot.
Are all the threads updating the same plot?

Manne

Manne Merak:

I think the problem in my application is, that many timers
start threads, they update the plots. If there is always one thread
running, the GUI never gets a chance to respond.

Just to be clear. You have multiple timers and with each timer start
you create a thread that does all the calculations and updates the plot.
Are all the threads updating the same plot?

Each plot has its own timer.
e.g. 10 repeating timers update 10 plots.
A call to threading.enumerate() shows the main thread and
the 10 timer threads.

I use RepeatTimer from Geoffrey Foster.
http://g-off.net/software/a-python-repeatable-threadingtimer-class

Each thread does:
- collect data
- make some numpy calculations
- calls wx.lib.plot.PlotGraphics() (no specific wx stuff I presume)
- wx.lib.plot.PlotCanvas.Draw() (wx stuff)
The execution time for one thread is about 0.1[s].

With this setup if I start about 10 timers/plots (repeat rate 1.0[s])
the GUI *does not* respond at all even after many minutes waiting.

Now I moved the call to wx.lib.plot.PlotCanvas.Draw() to a method in the
main thread and call it from the thread via wx.CallAfter().
With 10 timers/plots the GUI *does not* respond at all even after
many minutes waiting.

Now if I run the same app without calling wx.lib.plot.PlotCanvas.Draw()
(without any wx stuff in the threads) I see that
the GUI *does* respond even under heavy load:
40 timers/plots and a Unix load average of 16.
Sometimes the GUI takes several seconds to respond,
but it responds.

On a similar problem somebody suggested to add a call to wx.Yield().
I put it in the thread before or after the call to the method in
the main thread. No Change.
If I put SafeYield() the app crashes.

Is it possible to force the execution of the main thread with
a repeating timer?

Regards

···

--
Kurt Mueller

Manne Merak:

I think the problem in my application is, that many timers
start threads, they update the plots. If there is always one thread
running, the GUI never gets a chance to respond.

Just to be clear. You have multiple timers and with each timer start
you create a thread that does all the calculations and updates the plot.
Are all the threads updating the same plot?

Each plot has its own timer.
e.g. 10 repeating timers update 10 plots.
A call to threading.enumerate() shows the main thread and
the 10 timer threads.

I use RepeatTimer from Geoffrey Foster.
http://g-off.net/software/a-python-repeatable-threadingtimer-class

Each thread does:
- collect data
- make some numpy calculations
- calls wx.lib.plot.PlotGraphics() (no specific wx stuff I presume)
- wx.lib.plot.PlotCanvas.Draw() (wx stuff)
The execution time for one thread is about 0.1[s].

With this setup if I start about 10 timers/plots (repeat rate 1.0[s])
the GUI *does not* respond at all even after many minutes waiting.

Now I moved the call to wx.lib.plot.PlotCanvas.Draw() to a method in the
main thread and call it from the thread via wx.CallAfter().
With 10 timers/plots the GUI *does not* respond at all even after
many minutes waiting.

Now if I run the same app without calling wx.lib.plot.PlotCanvas.Draw()
(without any wx stuff in the threads) I see that
the GUI *does* respond even under heavy load:
40 timers/plots and a Unix load average of 16.
Sometimes the GUI takes several seconds to respond,
but it responds.

My guess is that one of the following things is happening:

* The worker threads are too busy and end up starving the main thread, preventing it from being able to execute. Try reducing the frequency that the worker threads do their thing to see how that affects things. Keep in mind that Python on multi-core machines has a real problem with multi-threading when one or more threads are CPU-bound. See http://blip.tv/file/2232410

* The main (gui) thread is getting blocked somehow. In other words, something in an event handler or other callback is getting stuck and not returning to the main loop, and so further events are not able to be dispatched.

* You're still doing some UI operation in a worker thread, possibly creating some UI object. If it's not giving you an error or simply crashing when this happens then it's possible that the UI object that was created "belongs" to the other thread and can cause problems when the main thread tries to service it in some way, like blocking until the owning thread responds, which it never will.

On a similar problem somebody suggested to add a call to wx.Yield().
I put it in the thread before or after the call to the method in
the main thread. No Change.
If I put SafeYield() the app crashes.

Don't call the yield functions from a worker thread. They are essentially just a nested event loop that runs until there are no more pending events. You obviously don't want events to be dispatched in the worker thread. In addition, SafeYield does all kinds of stuff with the UI objects before it enters the event loop to make them "safe," all of which are not legal to do in a non-gui thread.

Is it possible to force the execution of the main thread with
a repeating timer?

If you don't block it and you don't starve it then there shouldn't be a problem with it running normally.

···

On 12/12/09 1:37 AM, Kurt Mueller wrote:

--
Robin Dunn
Software Craftsman

Robin Dunn wrote:

My guess is that one of the following things is happening:

* The worker threads are too busy and end up starving the main thread,
preventing it from being able to execute. Try reducing the frequency
that the worker threads do their thing to see how that affects things.
Keep in mind that Python on multi-core machines has a real problem with
multi-threading when one or more threads are CPU-bound. See
http://blip.tv/file/2232410

* The main (gui) thread is getting blocked somehow. In other words,
something in an event handler or other callback is getting stuck and not
returning to the main loop, and so further events are not able to be
dispatched.

* You're still doing some UI operation in a worker thread, possibly
creating some UI object. If it's not giving you an error or simply
crashing when this happens then it's possible that the UI object that
was created "belongs" to the other thread and can cause problems when
the main thread tries to service it in some way, like blocking until the
owning thread responds, which it never will.

Is it possible to force the execution of the main thread with
a repeating timer?

If you don't block it and you don't starve it then there shouldn't be a
problem with it running normally.

Each worker thread does:
1) collect data
2) make some numpy calculations
3) calls wx.lib.plot.PlotGraphics() (no specific wx stuff I presume)
4) wx.lib.plot.PlotCanvas.Draw() (wx stuff) called with wx.CallAfter()
The execution time for one thread is about 0.1[s].

If I run a lot of worker threads with steps 1 to 4, the GUI does not
respond.

If I make a method in the main thread to execute step 4 in the main thread
and call this method from the worker threads with wx.CallAfter(),
the GUI does not respond.

If I leave out step 4 and run only steps 1 to 3, I can start as much
worker threads
as I want, the GUI does always respond (maybe very slow).

So I guess it is the wx.lib.plot.PlotCanvas.Draw() command that changes
the behavior of the GUI.

Regards

···

--
Kurt Mueller

Kurt Mueller wrote:

Each worker thread does:
1) collect data
2) make some numpy calculations
3) calls wx.lib.plot.PlotGraphics() (no specific wx stuff I presume)

Why are you presuming that? It's wx code -- it could well be making non-thread-safe wx calls -- worth checking out, anyway.

So I guess it is the wx.lib.plot.PlotCanvas.Draw() command that changes
the behavior of the GUI.

Could be -- unfortunately, as I learned from David Beazley's talk that Robin pointed us to -- threading in Python is tricky and unreliable, particularly with multiple processors/cores.

You might try adding a little sleep() call into your threads -- maybe that will allow some things to get cleaned up a bit.

Another thought:

I wonder if this is similar to the signal trapping issue (ctrl-C not working) that Avid BEazley talked about. If so, I suppose you could try running wx in a thread other than the main thread -- wx has to all runin the same thread, but it does not have to be the main one (though it's easiest to do that way!). You might look at the ipython project for an example of how to do that. now that I think about it, you might try running your code under iPython (with -wthread), and see if it behaves any differently there.

If all that fails, then you may need to give up on on threading -- either doing averyint the old-fashioned way, or using multi-processing instead -- the new-in-2.6 multiprocessing module may be helpful for that.

Good luck -- and do report back what you learn!

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Christopher Barker wrote:

Kurt Mueller wrote:

Each worker thread does:
1) collect data
2) make some numpy calculations
3) calls wx.lib.plot.PlotGraphics() (no specific wx stuff I presume)

Why are you presuming that? It's wx code -- it could well be making
non-thread-safe wx calls -- worth checking out, anyway.

I did now.
I put also wx.lib.plot.PlotGraphics() into the main thread.
It did not change anything.

So I guess it is the wx.lib.plot.PlotCanvas.Draw() command that changes
the behavior of the GUI.

Could be -- unfortunately, as I learned from David Beazley's talk that
Robin pointed us to -- threading in Python is tricky and unreliable,
particularly with multiple processors/cores.

You might try adding a little sleep() call into your threads -- maybe
that will allow some things to get cleaned up a bit.

I added a time.sleep(0.02) but no change, except that I could start
one more thread until the app blocked.

Another thought:

I wonder if this is similar to the signal trapping issue (ctrl-C not
working) that Avid BEazley talked about. If so, I suppose you could try
running wx in a thread other than the main thread -- wx has to all runin
the same thread, but it does not have to be the main one (though it's
easiest to do that way!).

That would be a hard job, because the app is now about 5000 lines of code.

You might look at the ipython project for an
example of how to do that. now that I think about it, you might try
running your code under iPython (with -wthread), and see if it behaves
any differently there.

I do not know iPython.
What would be the benefit using iPython in this situation?

If all that fails, then you may need to give up on on threading --
either doing averyint the old-fashioned way, or using multi-processing
instead -- the new-in-2.6 multiprocessing module may be helpful for that.

We have 2.5 for now.
There is no chance to update for the next few weeks
because of an other important project. Maybe later.

There is another weird problem with the app.
There is a right mouse click menu on the canvas of the plots.
When right clicking on a plot while heavy load, sometimes
not only the app freezes, but the whole X11 window freezes.
One cannot do anything but <ctl><alt><F1> to get a terminal.
After killing python, the rest of X11 comes to life again.
Linux 2.6.22.19-0.1-default, Core2duo
Python 2.5.1
wx 2.8.9.2

Maybe I'll take the time to make a sample app.

Regards

···

--
Kurt Mueller

Kurt Mueller wrote:

I put also wx.lib.plot.PlotGraphics() into the main thread.
It did not change anything.

darn.

You might look at the ipython project for an
example of how to do that. now that I think about it, you might try
running your code under iPython (with -wthread), and see if it behaves
any differently there.

I do not know iPython.
What would be the benefit using iPython in this situation?

It would be a way to test running wx in the non-main thread. I think you could simply fire up ipython with "ipython -wthread" then type "run YourMainScript.py"

And it would run, putting wx in a separate thread from the main (ipython) one. I have no idea if this would make any difference for you, but it would eliminate one possible issue.

Did you watch David Beazly's talk? It's pretty illuminating. In particular, he identified that if a you have a thread running computationally intensive stuff, it can totally starve a low-intensity IO thread -- wx may fall into that category, when it's simply waiting for events.

In his example, when a computationally intensive thread was running, it could take 100s of "tics" for an IO thread to run, that ultimately only use 3 tics to do its job. This was made much worse by multiple processors.

If you have more that one processor or core, you might try turning them off, ans see if things run better with only one.

If all that fails, then you may need to give up on on threading --
either doing averyint the old-fashioned way, or using multi-processing
instead -- the new-in-2.6 multiprocessing module may be helpful for that.

We have 2.5 for now.

look and see if it's been back-ported.

Maybe I'll take the time to make a sample app.

always a good idea.

Sorry we're not more help!

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Kurt Mueller schrieb:

Christopher Barker wrote:

Kurt Mueller wrote:

Each worker thread does:
1) collect data
2) make some numpy calculations
3) calls wx.lib.plot.PlotGraphics() (no specific wx stuff I presume)

So I guess it is the wx.lib.plot.PlotCanvas.Draw() command that changes
the behavior of the GUI.

Could be -- unfortunately, as I learned from David Beazley's talk that
Robin pointed us to -- threading in Python is tricky and unreliable,
particularly with multiple processors/cores.

I do not like threads at all! (Not only in Python)
I would rather like to use the multi-processing in 2.6. But...

If all that fails, then you may need to give up on on threading --
either doing averyint the old-fashioned way, or using multi-processing
instead -- the new-in-2.6 multiprocessing module may be helpful for that.

We have 2.5 for now.
There is no chance to update for the next few weeks
because of an other important project. Maybe later.

I gave up threading.

I put the callable of the "worker" methods in a list (besides other
information).
Then in a method called from EVT_IDLE a method is started to call all
"worker" methods in the list once.

No the problem arises that EVT_IDLE is only fired if there is something on
in the GUI like mouse movement.
I added a method called from EVT_IDLE that wx.CallLater(500, method)
calling wx.Frame.UpdateWindowUI() to have at least a EVT_EVENT every
500[ms].
500[ms] is tunable.

This construct runs now very well.
All mentioned problems are gone.
The caveat is, that the "worker" methods do not update regularly
because they are related to EVT_IDLE.

Thanks to everybody who helped.
Regards

···

--
Kurt Mueller

Something else you could consider is to call wx.WakeUpIdle() after you have gone through the list of workers. If there are pending events then they should be processed first, otherwise the event queue will "become empty" again and that will trigger the sending of another idle event.

···

On 12/18/09 6:43 AM, Kurt Mueller wrote:

No the problem arises that EVT_IDLE is only fired if there is something on
in the GUI like mouse movement.
I added a method called from EVT_IDLE that wx.CallLater(500, method)
calling wx.Frame.UpdateWindowUI() to have at least a EVT_EVENT every
500[ms].
500[ms] is tunable.

--
Robin Dunn
Software Craftsman