In my app, I have a main frame that can open a number of
other child frames. The child frames have on_close handlers
that check if any data needs to be saved, possibly presents
a dialog, and either closes or veto's the child frame's close.
In the main frame's on_close handler, I close all the child
windows and then want to close the main window if all the
child windows are closed, or not, if any are still open
(because the user canceled a save dialog or some other
problem closing a child window.).
However, when I check the child windows they all seem to
still open after I have closed them. I realize from the
docs that calling Close() just schedules their close rather
than actually closing them immediately, but I am not sure
how to get the results I want. I have tried putting Yield()
calls between closing the child windows and the check if
they're closed. And I have put Destroy() calls in the
child on_close handlers. These did not help.
How should the main frame check if all the child frames
were closed?
Demo program attached. Thanks for any help.
[close2.py1K ]import sys, pdb, wx, time
def main():
app = wx.App (redirect=0)
frame = MainFrame (None)
frame.Show (True)
app.MainLoop()
class MainFrame (wx.Frame):
def __init__(self, parent):
wx.Frame.__init__ (self, parent, -1, "Main", size=(320,270))
self.Bind (wx.EVT_CLOSE, self.onClose)
for n in (1,2,3): chld = ChildFrame (self, n)
def onClose \(self, evt\):
chlds = \[x for x in self\.GetChildren\(\) if isinstance\(x, ChildFrame\)\]
print >>sys\.stderr, "Initially open: %r" % \[x\.GetLabel\(\) for x in chlds\]
for x in chlds:
x\.Close\(\)
wx\.Yield\(\);time\.sleep\(\.5\); wx\.Yield\(\)
chlds = \[x for x in self\.GetChildren\(\) if isinstance\(x, ChildFrame\)\]
print >>sys\.stderr, "Still open: %r" % \[x\.GetLabel\(\) for x in chlds\]
if chlds: evt\.Veto\(\)
else: evt\.Skip\(\)
class ChildFrame (wx.Frame):
def __init__(self, parent, numb):
wx.Frame.__init__ (self, parent, -1, "Child %d" % numb, size=(320,270))
self.Bind (wx.EVT_CLOSE, self.onClose)
self.Show()
def onClose \(self, evt\):
name = self\.GetLabel\(\)
print >>sys\.stderr, "closing child %s" % name
self\.Destroy\(\)
if __name__ == '__main__': main ()