Understanding wx.Yield()

I have a general question with what is going on with a wx.Yield() call.

I am developing a transparent static text widget. I have extended
wx.StaticText and have bound EVT_PAINT to my paint() method. Things work
great ... when I call SetLabel() ... my custom paint() method gets called
and provides the painting behavior that I desire to create the effect of
transparency.

It was working fine until I started placing an additional amount of long
running code immediately following the SetLabel() call - and in this case I
get the old paint behavior. I did a little research and tried a wx.Yield()
immediately following the SetLabel() call ... and now it is working again.

My question is ... what is actually going on here? The best I can figure is
that my python code is running with the GIL in place ... such that when
wxWidgets tries to execute my paint() method it cannot get access to it ...
so rather than waiting ... it then moves up the event hierarchy (as if I had
called Skip()) and executes the default paint behavior for this class. Must
be the Yield() call allows my paint() code to be called?

Is this interpretation correct?

···

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/Understanding-wx-Yield-tp4293704p4293704.html
Sent from the wxPython-users mailing list archive at Nabble.com.

To my knowledge, wx.Yield creates a nested event loop, but as to knowing what a nested event loop is, other than that it is like wx.App inside another wx.App

···


Hi, I will kill all ads in google gmail.

They will all be dead and gone for all my emails to you. HA HA bye bye ads I just massacred you!!!

No. As Micah mentioned the various yield functions are essentially a nested event loop that reads and dispatches pending events from the event queue. When the queue is empty then the yield function returns.

The reason this fixes the problem you are seeing is that your long running tasks are preventing control from returning to the main event loop and so the paint event for your custom widget will just sit in the queue until the long running task completes and control is allowed to return to the main loop. Adding the yield allows those events to be processed sooner, but you may still have problems when the long running task does finally run because any new events that need to be processed during that time (for example, the user clicks a Cancel button) will still have to wait until the LRT is finished.

Another issue to watch out for when using a yield function is that it could lead to an unexpected recursion. For example you have a LRT that periodically calls yield so events can be processed, but one of the events that happens is one whose event handler starts the LRT again.

So usually it is better to use some other way to prevent blocking of events while running a the LRT, such as breaking it up into chunks that are run from EVT_IDLE handlers, or using a thread. See

  LongRunningTasks - wxPyWiki
  http://wiki.wxpython.org/Non-Blocking_Gui

···

On 4/9/11 5:33 PM, rocketman wrote:

I have a general question with what is going on with a wx.Yield() call.

I am developing a transparent static text widget. I have extended
wx.StaticText and have bound EVT_PAINT to my paint() method. Things work
great ... when I call SetLabel() ... my custom paint() method gets called
and provides the painting behavior that I desire to create the effect of
transparency.

It was working fine until I started placing an additional amount of long
running code immediately following the SetLabel() call - and in this case I
get the old paint behavior. I did a little research and tried a wx.Yield()
immediately following the SetLabel() call ... and now it is working again.

My question is ... what is actually going on here? The best I can figure is
that my python code is running with the GIL in place ... such that when
wxWidgets tries to execute my paint() method it cannot get access to it ...
so rather than waiting ... it then moves up the event hierarchy (as if I had
called Skip()) and executes the default paint behavior for this class. Must
be the Yield() call allows my paint() code to be called?

Is this interpretation correct?

--
Robin Dunn
Software Craftsman

Thanks Robin. As always your explanation and references were very useful as
I was able quickly get to the bottom of this.

···

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/Understanding-wx-Yield-tp4293704p4301646.html
Sent from the wxPython-users mailing list archive at Nabble.com.