Reputation: 1
When I try to call self.Close(True) in the top level Frame's EVT_CLOSE event handler, it raises a RuntimeError: maximum recursion depth exceeded. Here's the code:
from PicEvolve import PicEvolve
import wx
class PicEvolveFrame(wx.Frame):
def __init__(self, parent, id=-1,title="",pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,
name="frame"):
wx.Frame.__init__(self,parent,id,title,pos,size,style,name)
self.panel = wx.ScrolledWindow(self)
self.panel.SetScrollbars(1,1,600,400)
statusBar = self.CreateStatusBar()
menuBar = wx.MenuBar()
menu1 = wx.Menu()
m = menu1.Append(wx.NewId(), "&Initialize", "Initialize population with random images")
menuBar.Append(menu1,"&Tools")
self.Bind(wx.EVT_MENU,self.OnInit,m)
self.Bind(wx.EVT_CLOSE,self.OnClose)
self.SetMenuBar(menuBar)
def OnInit(self, event):
dlg = wx.TextEntryDialog(None,"Enter Population Size:","Population Size")
popSize = 0
if dlg.ShowModal() == wx.ID_OK:
popSize = int(dlg.GetValue())
self.pEvolver = PicEvolve(popSize,(200,200),True)
box = wx.BoxSizer(wx.VERTICAL)
filenames = []
for i in range(popSize):
filenames.append("img"+str(i)+".png")
for fn in filenames:
img = wx.Image(fn,wx.BITMAP_TYPE_ANY)
box.Add(wx.StaticBitmap(self.panel,wx.ID_ANY,wx.BitmapFromImage(img)), 0,wx.BOTTOM)
self.panel.SetSizer(box)
def OnClose(self,event):
self.Close(True)
class PicEvolveApp(wx.App):
def OnInit(self):
self.frame = PicEvolveFrame(parent=None,title="PicEvolve")
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == "__main__":
app = PicEvolveApp()
app.MainLoop()
Upvotes: 0
Views: 2551
Reputation: 650
def OnClose(self,event):
event.Skip()
see http://wiki.wxpython.org/EventPropagation
Upvotes: 0
Reputation: 88777
When you call window.Close it triggers EVT_CLOSE. Quoted from http://www.wxpython.org/docs/api/wx.CloseEvent-class.html
The handler function for EVT_CLOSE is called when the user has tried to close a a frame or dialog box using the window manager controls or the system menu. It can also be invoked by the application itself programmatically, for example by calling the wx.Window.Close function.
so obviously you will go into a infinite recursive loop. Instead in handler of EVT_CLOSE either destroy the window
def OnClose(self,event):
self.Destroy()
or Skip the event
def OnClose(self,event):
event.Skip(True)
or do not catch the EVT_CLOSE.
Edit: Btw why you want to catch the event, in other question you have put some comment, you should update the question accordingly, so that people can give better answers.
e.g when your program is still waiting on command prompt after close, it may mean you have some top level window still not closed.
To debug which one is still open, try this
for w in wx.GetTopLevelWindows():
print w
Upvotes: 1
Reputation: 33071
You don't need to catch EVT_CLOSE unless you want to do something special, like prompt the user to save. If you do that sort of thing, then call self.Destroy() instead. Right now you call OnClose when you hit the upper right "x", which then calls "Close", which fires the OnClose event....that's why you get the recursion error.
If you don't catch EVT_CLOSE and use self.Close() it should work. When it doesn't, then that usually means you have a timer, thread or hidden top-level window somewhere that also needs to be stopped or closed. I hope that made sense.
Upvotes: 0