Closing non-modal dialogs under 2.9

In all my code that ran on wxPython 2.8, I could close dialogs via the .Close() method, but now in 2.9 it seems that I must use .Destroy as well as .Close(). Is this true?

Below is how I would do it. The dialogs don't close unless I uncomment out the call to Destroy.

import wx

def button(parent, _id, label, event_handler):
     """
     Button that's auto-bound to an event
     """
     button = wx.Button(parent, _id, label)
     button.Bind(wx.EVT_BUTTON, event_handler)
     return button

class Frame(wx.Frame):
     def __init__(self):
         wx.Frame.__init__(self, None)
         dialogButton = button(self, wx.NewId(), "Show dialog", lambda evt: ShapeViewer(self).Show())

class ShapeViewer(wx.Dialog):
     def __init__(self, gui):
         wx.Dialog.__init__(self, gui)

         okButton = button(self, wx.ID_OK, "&OK", self.ok)
         cancelButton = button(self, wx.ID_CANCEL, "&Cancel", self.cancel)

         btnSizer = wx.StdDialogButtonSizer()
         btnSizer.AddButton(okButton)
         btnSizer.AddButton(cancelButton)
         btnSizer.Realize()

         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer.Add(btnSizer, 0, wx.TOP | wx.BOTTOM | wx.ALIGN_CENTRE, 15)
         self.SetSizer(sizer)

         self.SetFocus()
         self.SetEscapeId(cancelButton.GetId())

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

     def ok(self, event):
         #self.Destroy()
         self.Close()

     def cancel(self, event=None):
         self.Destroy()
         #self.Close()

     def on_close(self, event):
         event.Skip()

app = wx.App(False)
f = Frame()
f.Show()
app.MainLoop()

···

--
Steven Sproat, BSc
http://www.whyteboard.org/

Sorry, forgot to add version stuff - it's been a while since I posted here :slight_smile:

wx 2.9.4
python 2.7.2
Win XP SP3

···

On 25/11/2012 16:06, Steven Sproat wrote:

In all my code that ran on wxPython 2.8, I could close dialogs via the .Close() method, but now in 2.9 it seems that I must use .Destroy as well as .Close(). Is this true?

Below is how I would do it. The dialogs don't close unless I uncomment out the call to Destroy.

import wx

def button(parent, _id, label, event_handler):
    """
    Button that's auto-bound to an event
    """
    button = wx.Button(parent, _id, label)
    button.Bind(wx.EVT_BUTTON, event_handler)
    return button

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        dialogButton = button(self, wx.NewId(), "Show dialog", lambda evt: ShapeViewer(self).Show())

class ShapeViewer(wx.Dialog):
    def __init__(self, gui):
        wx.Dialog.__init__(self, gui)

        okButton = button(self, wx.ID_OK, "&OK", self.ok)
        cancelButton = button(self, wx.ID_CANCEL, "&Cancel", self.cancel)

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(okButton)
        btnSizer.AddButton(cancelButton)
        btnSizer.Realize()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(btnSizer, 0, wx.TOP | wx.BOTTOM | wx.ALIGN_CENTRE, 15)
        self.SetSizer(sizer)

        self.SetFocus()
        self.SetEscapeId(cancelButton.GetId())

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

    def ok(self, event):
        #self.Destroy()
        self.Close()

    def cancel(self, event=None):
        self.Destroy()
        #self.Close()

    def on_close(self, event):
        event.Skip()

app = wx.App(False)
f = Frame()
f.Show()
app.MainLoop()

--
Steven Sproat, BSc
http://www.whyteboard.org/

Please uninstall Python 2.7.2 and install Python 2.7.3 and try your wxPython code again :wink:

Hi,

Welcome back! I’ve always used Destroy() with dialogs. I think I tried Close() once and found that my dialogs would sometimes live on for an indeterminate amount of time after I’d closed them, which caused some odd bugs. Personally I think Destroy is the way to go. But we’ll see what Robin says.

  • Mike

I agree. I don't remember the specific details but I do remember that there were some changes related to closing dialogs. It looks like the default close event handlers in 2.9 don't call Destroy either, perhaps they did in 2.8 or perhaps it just inherited it from wx.TopLevelWindow instead of having an implementation in wx.Dialog.

···

On 11/26/12 6:40 AM, Mike Driscoll wrote:

Hi,

Welcome back! I've always used Destroy() with dialogs. I think I tried
Close() once and found that my dialogs would sometimes live on for an
indeterminate amount of time after I'd closed them, which caused some
odd bugs. Personally I think Destroy is the way to go. But we'll see
what Robin says.

--
Robin Dunn
Software Craftsman