local wx.Frame creation and garbage collector

Hi all,

I work on a wxPython application in which I bound the main frame to an wx.EVT_MENU. When the event is triggered the corresponding callback pops up a wx.Frame (I need it to be modeless).

Here is the code for the callback:

def on_open_my_frame(self, event):
f = MyFrame(self)
f.Show()

``

I am a bit surprised to see that this code works in the sense that the frame is opened and is functional. Indeed, I would expect troubles as the frame is 1) modeless 2) created locally which should trigger garbage collection and object destruction at the end of the scope. No ?

If so, does it mean that I must create my frame at the class level such as:

def on_open_my_frame(self, event):
if (getattr(self,“f”,None) is not None):
self.f.Destroy()
self.f = MyFrame(self)
self.f.Show()

``

what do you think ?

Thx a lot

Eric

No. In the wxWidgets code, the parent object (“self” in this case)
gets its own reference to the new object. That reference is not
released until the parent window is destroyed. Otherwise, perfectly
useful code like yours above would explode. It’s quite common, for
example, to create static text and button controls without keeping a
local reference.
You only need to do that if you need to refer to the dialog in other
functions. In the case of a dialog that gets reused, it’s more
common to create it once, then use Show and Hide to manage
visibility. What is the original code doing that you don’t like?

···

wrote:

ericpellegrini76@gmail.com

      I work on a wxPython application in which I bound the main

frame to an wx.EVT_MENU. When the event is triggered the
corresponding callback pops up a wx.Frame (I need it to be
modeless).

Here is the code for the callback:

def
on_open_my_frame(self, event):

                  f = MyFrame(self)

                  f.Show()

``

        I am a bit surprised to see

that this code works in the sense that the frame is
opened and is functional. Indeed, I would expect troubles as
the frame is 1) modeless 2) created locally which should
trigger garbage collection and object destruction at the end
of the scope. No ?

        If so, does it mean that I must

create my frame at the class level such as:

def on_open_my_frame(self, event):

                if (getattr(self,"f",None) is not None):

                    self.f.Destroy()

                self.f = MyFrame(self)

                self.f.Show()

``

      what do you think ?
-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

Hi Tim,

I did not thought that from the wxwidgets side there is still the parent window that holds a reference to the newly created window (probably a shared_ptr I guess). Now it is completely clear.

In fact the life cycle of this dialog is really bound to this method (i.e. no need for it elsewhere) so now with your explanations in hand I am definitely ok to have implemented it like so.

Thanks a lot for the explanations.

Eric

···

On Monday, November 20, 2017 at 7:59:29 PM UTC+1, ericpell...@gmail.com wrote:

Hi all,

I work on a wxPython application in which I bound the main frame to an wx.EVT_MENU. When the event is triggered the corresponding callback pops up a wx.Frame (I need it to be modeless).

Here is the code for the callback:

def on_open_my_frame(self, event):
f = MyFrame(self)
f.Show()

``

I am a bit surprised to see that this code works in the sense that the frame is opened and is functional. Indeed, I would expect troubles as the frame is 1) modeless 2) created locally which should trigger garbage collection and object destruction at the end of the scope. No ?

If so, does it mean that I must create my frame at the class level such as:

def on_open_my_frame(self, event):
if (getattr(self,“f”,None) is not None):
self.f.Destroy()
self.f = MyFrame(self)
self.f.Show()

``

what do you think ?

Thx a lot

Eric

Also relevant here is that there are extra references to the Python object (aka the proxy object) used for tracking and other things. For example, whenever a wxWindow pointer is returned from a C++ method, and if that object was originally created in Python, then that original Python proxy object is located and returned. There are also references to the proxy object held as part of the event bindings for methods of that class. And so on. Those extra references should all be properly cleaned up when the C++ object is destroyed, but it does mean that you can’t reliably predict when the proxy object itself will be garbage collected. However due to those extra references it does mean that we don’t need to hold on to the Python proxy objects for widgets in application code unless you need to access those objects later.

···

Robin Dunn

Software Craftsman

On Tuesday, November 21, 2017 at 12:39:04 AM UTC-8, ericpellegrini76@gmail.com wrote:

Hi Tim,

I did not thought that from the wxwidgets side there is still the parent window that holds a reference to the newly created window (probably a shared_ptr I guess). Now it is completely clear.

In fact the life cycle of this dialog is really bound to this method (i.e. no need for it elsewhere) so now with your explanations in hand I am definitely ok to have implemented it like so.

Thanks a lot for the explanations.

Eric

On Monday, November 20, 2017 at 7:59:29 PM UTC+1, ericpell...@gmail.com wrote:

Hi all,

I work on a wxPython application in which I bound the main frame to an wx.EVT_MENU. When the event is triggered the corresponding callback pops up a wx.Frame (I need it to be modeless).

Here is the code for the callback:

def on_open_my_frame(self, event):
f = MyFrame(self)
f.Show()

``

I am a bit surprised to see that this code works in the sense that the frame is opened and is functional. Indeed, I would expect troubles as the frame is 1) modeless 2) created locally which should trigger garbage collection and object destruction at the end of the scope. No ?

If so, does it mean that I must create my frame at the class level such as:

def on_open_my_frame(self, event):
if (getattr(self,“f”,None) is not None):
self.f.Destroy()
self.f = MyFrame(self)
self.f.Show()

``

what do you think ?

Thx a lot

Eric