[wxPython-dev] Problem with MenuItem.Destroy()

Robin Dunn robin at alldunn.com
Fri Dec 22 13:33:38 PST 2006


Paul McNett wrote:
> Robin Dunn wrote:
>> Sorry, I thought I had dealt with this bug already but the fix isn't 
>> in the code currently so maybe it accidentally got reverted or something.
> 
> Okay, I just found another problem, reproducible with the Menu.py example:
> 
> --- Menu.py.orig        2006-12-08 11:49:41.000000000 -0800
> +++ Menu.py     2006-12-22 09:04:45.000000000 -0800
> @@ -81,6 +81,9 @@
>          item = wx.MenuItem(menu5, 500, "&Smile!\tCtrl+S", "This one has 
> an icon")
>          item.SetBitmap(images.getSmilesBitmap())
>          menu5.AppendItem(item)
> +        menu5.RemoveItem(item)
> +        menu4.AppendItem(item)
> +        #item.Destroy()
> 
>          # Shortcuts
>          menu5.Append(501, "Interesting thing\tCtrl+A", "Note the 
> shortcut!")
> 
> 
> ====
> We already know that the commented item.Destroy() segfaults in wx2.8.0.1 
> but not in wx 2.6. What we know now is that while the RemoveItem() works 
> fine in both, the AppendItem() does not (segfault in 2.8).
> 
> The good news is that I believe all the remaining issues in Dabo come 
> down to this problem. We tend to move menu items around...

Try it like this:

         menu5.AppendItem(item)
         item = menu5.RemoveItem(item)
         menu4.AppendItem(item)

I'm not sure if that will work around the problem in 2.8.0.1 but it does 
in the current CVS.

In a nutshell the problem is this:  The wx.MenuItem class isn't able to 
use the OOR capabilities that I can use for wx.Window and etc., so the 
normal SWIG proxy mechanisms are used instead.  So that means that each 
time a wx.MenuItem is returned from a method a new Python proxy object 
is created for it, even if one wrapping the same C++ object already 
exists.  Normally this is all transparent and we don't care about it, 
but object ownership rules are tossing a spanner in the works here... 
AppendItem takes ownership of the C++ object, so I set a flag that tells 
the proxy object that it no longer owns the C++ object and so it doesn't 
try to destroy it when the proxy is GC'd.  However RemoveItem 
relinquishes ownership of the C++ object, so the proxy used for the 
return value is set to own the C++ object.  In your original code since 
you were not assigning the return value proxy to a variable it was 
getting GC's immediately and so the C++ object was being destroyed. 
However since the proxy used for the parameter points to the same (now 
destroyed) C++ object when you try to use it for the next AppendItem you 
get the segfault.

Since we know that with RemoveItem that the parameter and the return 
value will always be the same C++ object I think that there should be a 
way that I can fix this such that either code snippet will work as 
expected.  I'll see what I can do.

> 
> It is possible we are seeing similar trouble with removing/adding items 
> to sizers, but I don't have proof of that yet.

wx.SizerItems could very well have the same kinds of problems.  Let me 
know if you can track down specific test cases.


-- 
Robin Dunn
Software Craftsman
http://wxPython.org  Java give you jitters?  Relax with wxPython!





More information about the wxpython-dev mailing list