wx.Dialog once more...

Hello wxPython-users,

def doSomeDlg():
   dlg = wx.Dialog(...)
   return dlg.ShowModal()
is this correct?

No. You still need to destroy it:

def doSomeDlg():
    dlg = wx.Dialog()
    result = dlg.ShowModal()
    dlg.Destroy()
    return result

but if python object dlg is automaticly destroyed,
why it cannot destroy its underlying wxPython object if it
not yet destroyed.

In my database project I use method validator.TransferFromWindow when
dealing with results of dialog window, thus I dont need to read dlg values
upon successful exiting from dialog. But as in c/c++ I may forget
explicitly destroy dialog. And to find why application does not
exit after closing last visible window is very hard. After all dlg
object is destroyed automatically. Why cant we use this lucky chance.

Those questions are arisen because I get some problem in this code:
variant 1:
class Catalog(wx.Frame):
    def __init__(self, parent):
        ...
        wx.EVT_LIST_COL_CLICK(self, listId, self.OnColLabelClick)

    def OnColLabelClick(self, evt):
        col = evt.GetColumn()
        if col == 3:
            dlg = priceEditDlg(self, ...)
            dlg.ShowModal()
            dlg.Destroy()
when clicking on column label of report wx.ListCtrl I show some
dialog. But just after creating and displaying this dialog very first
click on system button "Close" (small cross in the upper right
corner of the window) does nothing absolutely. But dlg window
is looking active. Only second click on that button does close
dialog! Whats the matter?

variant 2:
class Catalog(wx.Frame):
    def __init__(self, parent):
        ...
        wx.EVT_LIST_COL_CLICK(self, listId, self.OnColLabelClick)

    def OnColLabelClick(self, evt):
        col = evt.GetColumn()
        if col == 3:
            dlg = priceEditDlg(self, ...)
            wx.CallAfter(dlg.ShowModal)
this works as expected - dialog disappears after first click on
system close button. But undestroyed dialog window gets somehow
been destroyed somewhere because application is exiting correctly.
I cannot explain this tricky behaviour.
I am using wxPython 2.4.1.2, Python 2.2.3, Windows 98

···

--
bye,
kvp

Hotmail wrote:

Hello wxPython-users,

def doSomeDlg():
  dlg = wx.Dialog(...)
  return dlg.ShowModal()
is this correct?

No. You still need to destroy it:

def doSomeDlg():
   dlg = wx.Dialog()
   result = dlg.ShowModal()
   dlg.Destroy()
   return result

but if python object dlg is automaticly destroyed,
why it cannot destroy its underlying wxPython object if it
not yet destroyed.

It's a long story...

The short answer is that it's due to wxDialog's usage pattern from C++ being slightly different from the other wxWindows, but not originally being able to express that difference in wxPython without a lot of pain. Just requiring people to use Destroy() seemed like a reasonable tradeoff.

Since then the addition of OOR support has complicated things a bit in that the C++ object now holds a reference to the Python object, and so the __del__, if it exists, will not even be called until after the C++ object has been destroyed and so there is no sense in adding a __del__ for wxDialog that calls Destroy.

In my database project I use method validator.TransferFromWindow when
dealing with results of dialog window, thus I dont need to read dlg values
upon successful exiting from dialog. But as in c/c++ I may forget
explicitly destroy dialog. And to find why application does not
exit after closing last visible window is very hard. After all dlg
object is destroyed automatically. Why cant we use this lucky chance.

Those questions are arisen because I get some problem in this code:
variant 1:
class Catalog(wx.Frame):
    def __init__(self, parent):
        ...
        wx.EVT_LIST_COL_CLICK(self, listId, self.OnColLabelClick)

    def OnColLabelClick(self, evt):
        col = evt.GetColumn()
        if col == 3:
            dlg = priceEditDlg(self, ...)
            dlg.ShowModal()
            dlg.Destroy()
when clicking on column label of report wx.ListCtrl I show some
dialog. But just after creating and displaying this dialog very first
click on system button "Close" (small cross in the upper right
corner of the window) does nothing absolutely. But dlg window
is looking active. Only second click on that button does close
dialog! Whats the matter?

I don't know, probably some interaction with the nested event loop in ShowModal and the unfinished handler for EVT_LIST_COL_CLICK.

variant 2:
class Catalog(wx.Frame):
    def __init__(self, parent):
        ...
        wx.EVT_LIST_COL_CLICK(self, listId, self.OnColLabelClick)

    def OnColLabelClick(self, evt):
        col = evt.GetColumn()
        if col == 3:
            dlg = priceEditDlg(self, ...)
            wx.CallAfter(dlg.ShowModal)
this works as expected - dialog disappears after first click on
system close button. But undestroyed dialog window gets somehow
been destroyed somewhere because application is exiting correctly.

Since the dialog has a parent window the dialog will be destroyed by the parent when it is destroyed. But the dialog will still exist and consume it's system resources until then. Perhaps a better approach would be to wxCallAfter some other function that then creates, shows and destroys the dialog:

     def OnColLabelClick(self, evt):
         col = evt.GetColumn()
         if col == 3:
              wx.CallAfter(self.doShowPriceEditDlg)

     def doShowPriceEditDlg(self):
          dlg = priceEditDlg(self, ...)
          dlg.ShowModal()
   dlg.Destroy()

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!