local wx.Frame creation and garbage collector

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

local wx.Frame creation and garbage collector

ericpellegrini76
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

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: local wx.Frame creation and garbage collector

Tim Roberts

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 ?


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.


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 ?

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?
-- 
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: local wx.Frame creation and garbage collector

ericpellegrini76
In reply to this post by ericpellegrini76
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, [hidden email] 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

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: local wx.Frame creation and garbage collector

Robin Dunn
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
http://wxPython.org



On Tuesday, November 21, 2017 at 12:39:04 AM UTC-8, [hidden email] 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, [hidden email] 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

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.