wx.Yield() appears not to work properly in wxPython 2.9.4.1.

77 views
Skip to first unread message

Edward d'Auvergne

unread,
Oct 17, 2012, 8:09:15 AM10/17/12
to wxpytho...@googlegroups.com
Hi,

I've noticed a recent problem in wxPython, though maybe this lies on
the wxGTK side. wx.Yield() no longer appears to flush all events.
The following code demonstrates this:

-----
import wx

class Main(wx.Frame):
def __init__(self):
super(Main, self).__init__(parent=None, id=-1, title="wx.Yield test")
self.gauge = wx.Gauge(self, id=-1, range=100, style=wx.GA_SMOOTH)
wx.CallAfter(self.gauge.SetValue, 100)
wx.Yield()
print(self.gauge.GetValue())

app = wx.App(False)
frame = Main()
frame.Show(True)
app.MainLoop()
-----

I would expect that the print call would print out 100, as it does in
the 2.8 versions and earlier 2.9 versions, but instead I see 0! Any
ideas as to what this problem is or where a better place to ask is?

Cheers,

Edward

Edward d'Auvergne

unread,
Oct 17, 2012, 8:59:23 AM10/17/12
to wxpytho...@googlegroups.com
Sorry, I left out some info.  This is on a 64-bit GNU/Linux system on both Python 2.6 and 2.7 with wxPython 2.9.4.0 with the patch applied to update to 2.9.4.1 "gtk2 (classic)".

Regards,

Edward


--

Edward d'Auvergne
Software Artisan
http://www.nmr-relax.com

Tim Roberts

unread,
Oct 17, 2012, 12:50:23 PM10/17/12
to wxpytho...@googlegroups.com
Edward d'Auvergne wrote:
> I've noticed a recent problem in wxPython, though maybe this lies on
> the wxGTK side. wx.Yield() no longer appears to flush all events.
> ...
> I would expect that the print call would print out 100, as it does in
> the 2.8 versions and earlier 2.9 versions, but instead I see 0! Any
> ideas as to what this problem is or where a better place to ask is?

I think it was a fluke that it ever worked. It's a timing issue. You
are calling this in Main.__init__, which has to run to completion before
the event loop ever gets launched (in the call to app.MainLoop). So,
although the call to wx.CallAfter has, indeed, queued up an event,
there's no one looking at the event loop to drain those events, so
there's nothing for Yield to do.

It's possible this changed because of some internal implementation
detail, but I think you were relying on undefined behavior to begin
with. wx.Yield is meaningless unless an event loop is running.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Robin Dunn

unread,
Oct 17, 2012, 9:13:20 PM10/17/12
to wxpytho...@googlegroups.com
On 10/17/12 9:50 AM, Tim Roberts wrote:
> It's possible this changed because of some internal implementation
> detail, but I think you were relying on undefined behavior to begin
> with. wx.Yield is meaningless unless an event loop is running.

Yes, there has been some changes in the implementation of the event
loops, and also in how yielding is done. Part of the changes is that
yield doesn't do anything until the first event loop (usually the
MainLoop method) has been entered.

--
Robin Dunn
Software Craftsman
http://wxPython.org

Edward d'Auvergne

unread,
Oct 18, 2012, 8:22:55 AM10/18/12
to wxpytho...@googlegroups.com
Obviously this is a mistake in building the test app.  I've attached a better script which shows this problem inside of the main application loop.  The behaviour inside and outside of the main loop is identical - 2.9.4.1 prints out '0' and 2.8 prints out '100'.  A quick test on Win7 with 2.9.4.0 prints out '100'.

Cheers,

Edward
test_wx_yield.py

Edward d'Auvergne

unread,
Oct 18, 2012, 9:31:16 AM10/18/12
to wxpytho...@googlegroups.com
Here is an even prettier demonstration.


Regards,

Edward


--

Edward d'Auvergne
http://www.nmr-relax.com
test_wx_yield.py

Edward d'Auvergne

unread,
Oct 18, 2012, 9:48:04 AM10/18/12
to wxpytho...@googlegroups.com
Here is another example using wx.grid.Grid instead of wx.Gauge, just to demonstrate that the problem lies in wx.Yield().  Both the grid and gauge wx elements fail in the test suite for the software relax (http://www.nmr-relax.com) when testing the 2.9.4.x wxPython code, but I would guess this is a problem for all wx elements together with the yield call.
test_grid_set.py

Robin Dunn

unread,
Oct 18, 2012, 2:29:22 PM10/18/12
to wxpytho...@googlegroups.com
Please create a ticket for this at trac.wxwidgets.org. Set its
Component to wxGTK, and explain that it appears that events posted to
the application object with wxPostEvent are not being processed while in
a yield on wxGTK, but that they are on other platforms. (This is so the
C++ guys will be able to figure it out without needing to know how
wxPython's CallAfter works.)

Edward d'Auvergne

unread,
Oct 18, 2012, 3:41:20 PM10/18/12
to wxpytho...@googlegroups.com
Done:

http://trac.wxwidgets.org/ticket/14760

I hope I've explained it correctly.  Anyway, thanks for the clear pointers.  And looking forward to seeing the phoenix take over the 2.9 line one day soon ;)


--

Edward d'Auvergne
relax project admin (http://www.nmr-relax.com)
Reply all
Reply to author
Forward
0 new messages