当我尝试在顶级Frame的EVT_CLOSE事件处理程序中调用self.Close(True)时,它会引发RuntimeError:超出最大递归深度。这是代码:
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()
答案 0 :(得分:1)
当你调用window.Close时会触发EVT_CLOSE。 引自http://www.wxpython.org/docs/api/wx.CloseEvent-class.html
很明显,你会进入一个无限的递归循环。而是在EVT_CLOSE的处理程序中破坏窗口EVT_CLOSE的处理函数是 在用户尝试时调用 使用关闭框架或对话框 窗口管理器控制或 系统菜单。它也可以被调用 应用程序本身 以编程方式,例如 调用wx.Window.Close函数。
def OnClose(self,event):
self.Destroy()
或略过事件
def OnClose(self,event):
event.Skip(True)
或者没有抓住EVT_CLOSE。
编辑: 顺便说一下你为什么要抓住这个事件,在其他问题上你已经发表了一些评论,你应该相应地更新问题,以便人们可以给出更好的答案。
例如,当您的程序在关闭后仍然在命令提示符处等待时,可能意味着您仍然没有关闭某个顶级窗口。
要调试哪一个仍处于打开状态,请尝试此
for w in wx.GetTopLevelWindows():
print w
答案 1 :(得分:0)
def OnClose(self,event):
event.Skip()
答案 2 :(得分:0)
除非您想要做一些特别的事情,比如提示用户保存,否则您不需要捕获EVT_CLOSE。如果你做那种事情,那么请调用self.Destroy()。现在,当你点击右上方的“x”时调用OnClose,然后调用“Close”,它会触发OnClose事件....这就是你得到递归错误的原因。
如果你没有捕获EVT_CLOSE并使用self.Close()它应该工作。如果没有,那通常意味着你有一个计时器,线程或隐藏的顶级窗口,也需要停止或关闭。我希望这是有道理的。