[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