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

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

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

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, timr@probo.com
Providenza & Boekelheide, Inc.

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.

···

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.

--
Robin Dunn
Software Craftsman

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 (698 Bytes)

···

On Thursday, 18 October 2012 03:13:25 UTC+2, Robin Dunn wrote:

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
Software Artisan
http://www.nmr-relax.com

Here is an even prettier demonstration.

Regards,

Edward

test_wx_yield.py (935 Bytes)

···

Edward d’Auvergne
http://www.nmr-relax.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 (1023 Bytes)

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.)

···

On 10/18/12 6:48 AM, Edward d'Auvergne wrote:

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.

--
Robin Dunn
Software Craftsman

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 :wink:

···

Edward d’Auvergne
relax project admin (http://www.nmr-relax.com)