Either a bug or a question - where can I "do" my destruction?

Hello,

I have done some searching but as you can imagine the results are polluted with loads of tutorials.

the situation is this:
I derive from TreeListCtrl (in gizmos) and it binds to something not in wxWidgets to receive events.

When it is destroyed it must unbind, obviously.

I don't really want to use the python "__del__" method because... well destruction is something I want to be deterministic, this could be called after the thing it bound to is actually destroyed, or something...

I've tried binding to EVT_CLOSE in the class, I don't get an event when the parent frame is closed.

I've also overridden the "Close" and "Destroy" methods of TreeListCtrl, they are also not called when the frame is closed.

Either this is a bug, or I am doing it wrong, where do I get a chance to do my destructor?

(I mainly use wxWidgets you see, I love wxPython though, largely because nothing changes, I just discovered that the dot was optional (example wx.Expand verses wxExpand ) by spotting it and there being a lack of errors, I am now even happier! I don't even have to force myself to use the dot! I am not sure how you achieved that (from "import wx"))

Sorry if this is a dumb question, I have spent a good 20 minutes searching and just getting tutorial after silly question after tutorial.

Alec

I won’t judgde the necessity to del bound items (as long as you do not provide a minimal example that it is indeed necessary, I will claim that it is not).

I’ve tried binding to EVT_CLOSE in the class, I don’t get an event when
the parent frame is closed.

Have a look at the wxWidgets docs regarding the wxCloseEvent. When you scroll further down, you will notice:

"[…]Event macros:

  • EVT_CLOSE(func):
    Process a wxEVT_CLOSE_WINDOW command event, supplying the member function. This event applies to wxFrame and wxDialog classes.

[…]"

So you have to bind your destructor method to the parent frame, not your derived control.

···

On Thursday, July 10, 2014 9:08:28 AM UTC+2, Alec Teal wrote:

Hi Alec,

Hello,

I have done some searching but as you can imagine the results are polluted with loads of tutorials.

the situation is this:
I derive from TreeListCtrl (in gizmos) and it binds to something not in wxWidgets to receive events.

When it is destroyed it must unbind, obviously.

Are you sure you have to unbind? In my code I just have unbind on some floatcanvas stuff where I need to bind/unbind depending the mode a user selects, otherwise wxPython does the 'right thing' for me.

I don't really want to use the python "__del__" method because... well destruction is something I want to be deterministic, this could be called after the thing it bound to is actually destroyed, or something...

I've tried binding to EVT_CLOSE in the class, I don't get an event when the parent frame is closed.

I've also overridden the "Close" and "Destroy" methods of TreeListCtrl, they are also not called when the frame is closed.

I think that should work, can you show some sample code showing the problem. MakingSampleApps - wxPyWiki

Either this is a bug, or I am doing it wrong, where do I get a chance to do my destructor?

(I mainly use wxWidgets you see, I love wxPython though, largely because nothing changes, I just discovered that the dot was optional (example wx.Expand verses wxExpand ) by spotting it and there being a lack of errors, I am now even happier! I don't even have to force myself to use the dot! I am not sure how you achieved that (from "import wx"))

sorry don't get this

If you do 'import wx' then it would be 'wx.EXPAND'

Werner

···

On 7/10/2014 9:08, Alec Teal wrote:

Hi Alec,

Hello,

I have done some searching but as you can imagine the results are polluted with loads of tutorials.

the situation is this:
I derive from TreeListCtrl (in gizmos) and it binds to something not in wxWidgets to receive events.

When it is destroyed it must unbind, obviously.

Are you sure you have to unbind? In my code I just have unbind on some floatcanvas stuff where I need to bind/unbind depending the mode a user selects, otherwise wxPython does the 'right thing' for me.

"Something **NOT** in wxWidgets" - Yes I am sure I have to bind to it, and unbind when I am done.

I don't really want to use the python "__del__" method because... well destruction is something I want to be deterministic, this could be called after the thing it bound to is actually destroyed, or something...

I've tried binding to EVT_CLOSE in the class, I don't get an event when the parent frame is closed.

I've also overridden the "Close" and "Destroy" methods of TreeListCtrl, they are also not called when the frame is closed.

I think that should work, can you show some sample code showing the problem. MakingSampleApps - wxPyWiki

import wx
class MyApp(wxApp):
     def __init__(self):
         wxApp.__init__(self)
     def OnInit(self):
         frame = MyFrame()
         frame.Show()

class MyFrame(wxFrame):
     def __init__(self):
         wxFrame.__init__(self,None,wxID_ANY,title="Whatever",size=(1000,500))
         sizer = wxBoxSizer(wxVERTICAL)
         self.SetSizer(sizer)
         sizer.Add(MyThing(self))

class MyThing(wx.gizmos.TreeListCtrl):
     def __init__(self,parent):
         wx.gizmos.TreeListCtrl(self,parent,wxID_ANY)

         EVT_CLOSE(self,self.onClose)
         print "I would do that binding Alec is on about here"

     def onClose(self,evt):
         print "I'd like to unbind here (or something)"

I quite literally wrote this in my email client. To quote myself:

"I've tried binding to EVT_CLOSE in the class, I don't get an event when the parent frame is closed. "

I've also tried overriding Close and Destroy (then calling the base's Close and Destroy of course) with something like "print "Close caught"" or something - nothing.

Either this is a bug, or I am doing it wrong, where do I get a chance to do my destructor?

(I mainly use wxWidgets you see, I love wxPython though, largely because nothing changes, I just discovered that the dot was optional (example wx.Expand verses wxExpand ) by spotting it and there being a lack of errors, I am now even happier! I don't even have to force myself to use the dot! I am not sure how you achieved that (from "import wx"))

sorry don't get this

If you do 'import wx' then it would be 'wx.EXPAND'

Yet "wxEXPAND" works, and EVT_BUTTON, no wx needed, brilliant stuff! I only noticed because I saw sample code that had wx. This makes it even easier for us C++ lot to use wxPython easily.

···

On 10/07/14 08:56, Werner wrote:

On 7/10/2014 9:08, Alec Teal wrote:

Werner

You’re a star, thanks for the quick response.

One more quick question, if I have this handler:

def onClose(self,evt):

    print "Closing"

    evt.Skip()

I get one "Closing" on stdout, where as:

def onClose(self,evt):

    evt.Skip()

    print "Closing"

shows "Closing" twice, what's going on here?

Skip just means "use the next match" instead (command events don't

rise up the event tables) why is the event coming back down yet not
endlessly looping?

Alec
···

On 10/07/14 08:41, nepix32 wrote:

      On Thursday, July 10, 2014 9:08:28 AM UTC+2, Alec Teal wrote:
      I won't judgde the necessity to __del__ bound items (as

long as you do not provide a minimal example that it is
indeed necessary, I will claim that it is not).

      I've

tried binding to EVT_CLOSE in the class, I don’t get an event
when

      the parent frame is closed.

Have a look at the wxWidgets
docs regarding the wxCloseEvent
. When you scroll further
down, you will notice:

"[…]Event macros:

  • EVT_CLOSE(func):
    Process a wxEVT_CLOSE_WINDOW
    command event, supplying the member function. This event
    applies to wxFrame and wxDialog classes.

[…]"

      So you have to bind your destructor method to the parent

frame, not your derived control.

Hi, Alec,

I won't judgde the necessity to __del__ bound items (as long as you do not
provide a minimal example that it *is* indeed necessary, I will claim that
it is not).

I've tried binding to EVT_CLOSE in the class, I don't get an event when
the parent frame is closed.

Have a look at the wxWidgets docs regarding the wxCloseEvent. When you
scroll further down, you will notice:

"[…]Event macros:

EVT_CLOSE(func):
Process a wxEVT_CLOSE_WINDOW command event, supplying the member function.
This event applies to wxFrame and wxDialog classes.

[…]"
So you have to bind your destructor method to the parent frame, not your
derived control.

You're a star, thanks for the quick response.

One more quick question, if I have this handler:

def onClose(self,evt):
    print "Closing"
    evt.Skip()

I get one "Closing" on stdout, where as:

def onClose(self,evt):
    evt.Skip()
    print "Closing"

shows "Closing" twice, what's going on here?

Skip just means "use the next match" instead (command events don't rise up
the event tables) why is the event coming back down yet not endlessly
looping?

You made a mistake here.
Calling Skip() means to continue processing the event after you are
done with the handler.
If you don't call Skip(), the event will just be eaten by the program
and no default handler will
be executed.

Thank you.

···

On Thu, Jul 10, 2014 at 1:16 AM, Alec Teal <a.teal@warwick.ac.uk> wrote:

On 10/07/14 08:41, nepix32 wrote:
On Thursday, July 10, 2014 9:08:28 AM UTC+2, Alec Teal wrote:

Alec

--
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 wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hi Alec,

oops, should have gone to the list.

I think that should work, can you show some sample code showing the
problem. MakingSampleApps - wxPyWiki

please do read the above link, I won't try to run your code as it means I take guesses at what you do and takes more time for me.

import wx
class MyApp(wxApp):
    def __init__(self):
        wxApp.__init__(self)
    def OnInit(self):
        frame = MyFrame()
        frame.Show()

class MyFrame(wxFrame):
    def __init__(self):
wxFrame.__init__(self,None,wxID_ANY,title="Whatever",size=(1000,500))
        sizer = wxBoxSizer(wxVERTICAL)
        self.SetSizer(sizer)
        sizer.Add(MyThing(self))

class MyThing(wx.gizmos.TreeListCtrl):
    def __init__(self,parent):
        wx.gizmos.TreeListCtrl(self,parent,wxID_ANY)

        EVT_CLOSE(self,self.onClose)

That is old style of doing it and won't work in recent versions of wxPython, it should be.

self.Bind(wx.EVT_CLOSE, self.onClose)

print "I would do that binding Alec is on about here"

You might also want to write this in Py3 syntax, works in Py2.7 and maybe earlier.
print("I would do that binding Alec is on about here")

    def onClose(self,evt):
        print "I'd like to unbind here (or something)"

I quite literally wrote this in my email client. To quote myself:

"I've tried binding to EVT_CLOSE in the class, I don't get an event
when the parent frame is closed. "

I've also tried overriding Close and Destroy (then calling the base's
Close and Destroy of course) with something like "print "Close
caught"" or something - nothing.

Either this is a bug, or I am doing it wrong, where do I get a
chance to do my destructor?

(I mainly use wxWidgets you see, I love wxPython though, largely
because nothing changes, I just discovered that the dot was optional
(example wx.Expand verses wxExpand ) by spotting it and there being
a lack of errors, I am now even happier! I don't even have to force
myself to use the dot! I am not sure how you achieved that (from
"import wx"))

sorry don't get this

If you do 'import wx' then it would be 'wx.EXPAND'

Yet "wxEXPAND" works, and EVT_BUTTON, no wx needed, brilliant stuff! I
only noticed because I saw sample code that had wx. This makes it even
easier for us C++ lot to use wxPython easily.

No expert here, but that might work if you have a 'from wx import *' or something like that but just doing 'import wx' (which is the recommended form) will not give you 'EVT_BUTTON' or 'wxEXPAND'.

There is still sample code out there from the 'old days' which usesfrom wxPython.wx import *' which should not be used as it is gone in recent versions of wxPython.

Werner

···

On 7/10/2014 10:05, Alec Teal wrote:

On 10/07/14 08:56, Werner wrote: ...

That's what I meant, typo, none the less if I Skip then do something (eg print) why do I see the message twice?

Alec

···

On 10/07/14 09:25, Igor Korot wrote:

Hi, Alec,

On Thu, Jul 10, 2014 at 1:16 AM, Alec Teal<a.teal@warwick.ac.uk> wrote:

On 10/07/14 08:41, nepix32 wrote:

On Thursday, July 10, 2014 9:08:28 AM UTC+2, Alec Teal wrote:
I won't judgde the necessity to __del__ bound items (as long as you do not
provide a minimal example that it *is* indeed necessary, I will claim that
it is not).

I've tried binding to EVT_CLOSE in the class, I don't get an event when
the parent frame is closed.

Have a look at the wxWidgets docs regarding the wxCloseEvent. When you
scroll further down, you will notice:

"[…]Event macros:

EVT_CLOSE(func):
Process a wxEVT_CLOSE_WINDOW command event, supplying the member function.
This event applies to wxFrame and wxDialog classes.

[…]"
So you have to bind your destructor method to the parent frame, not your
derived control.

You're a star, thanks for the quick response.

One more quick question, if I have this handler:

def onClose(self,evt):
     print "Closing"
     evt.Skip()

I get one "Closing" on stdout, where as:

def onClose(self,evt):
     evt.Skip()
     print "Closing"

shows "Closing" twice, what's going on here?

Skip just means "use the next match" instead (command events don't rise up
the event tables) why is the event coming back down yet not endlessly
looping?

You made a mistake here.
Calling Skip() means to continue processing the event after you are
done with the handler.
If you don't call Skip(), the event will just be eaten by the program
and no default handler will
be executed.

Thank you.

...

One more quick question, if I have this handler:

def onClose(self,evt):
     print "Closing"
     evt.Skip()

I get one "Closing" on stdout, where as:

def onClose(self,evt):
     evt.Skip()
     print "Closing"

shows "Closing" twice, what's going on here?

Skip just means "use the next match" instead (command events don't rise up
the event tables) why is the event coming back down yet not endlessly
looping?

You made a mistake here.
Calling Skip() means to continue processing the event after you are
done with the handler.
If you don't call Skip(), the event will just be eaten by the program
and no default handler will
be executed.

Thank you.

That's what I meant, typo, none the less if I Skip then do something (eg print) why do I see the message twice?

Where you please 'evt.Skip()' in your event handler does not matter.

Do you bind 'onClose' from two different places?

Werner

···

On 7/10/2014 10:37, Alec Teal wrote:

On 10/07/14 09:25, Igor Korot wrote:

...

One more quick question, if I have this handler:

def onClose(self,evt):
     print "Closing"
     evt.Skip()

I get one "Closing" on stdout, where as:

def onClose(self,evt):
     evt.Skip()
     print "Closing"

shows "Closing" twice, what's going on here?

Skip just means "use the next match" instead (command events don't
rise up
the event tables) why is the event coming back down yet not endlessly
looping?

You made a mistake here.
Calling Skip() means to continue processing the event after you are
done with the handler.
If you don't call Skip(), the event will just be eaten by the program
and no default handler will
be executed.

Thank you.

That's what I meant, typo, none the less if I Skip then do something
(eg print) why do I see the message twice?

Where you please 'evt.Skip()' in your event handler does not matter.

should be:
Where you place .....

···

On 7/10/2014 10:42, Werner wrote:

On 7/10/2014 10:37, Alec Teal wrote:

On 10/07/14 09:25, Igor Korot wrote:

Do you bind 'onClose' from two different places?

Werner