wxPython wx.Close创建运行时错误

时间:2010-08-02 19:49:20

标签: python wxpython

当我尝试在顶级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() 

3 个答案:

答案 0 :(得分:1)

当你调用window.Close时会触发EVT_CLOSE。 引自http://www.wxpython.org/docs/api/wx.CloseEvent-class.html

  

EVT_CLOSE的处理函数是   在用户尝试时调用   使用关闭框架或对话框   窗口管理器控制或   系统菜单。它也可以被调用   应用程序本身   以编程方式,例如   调用wx.Window.Close函数。

很明显,你会进入一个无限的递归循环。而是在EVT_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()

请参阅http://wiki.wxpython.org/EventPropagation

答案 2 :(得分:0)

除非您想要做一些特别的事情,比如提示用户保存,否则您不需要捕获EVT_CLOSE。如果你做那种事情,那么请调用self.Destroy()。现在,当你点击右上方的“x”时调用OnClose,然后调用“Close”,它会触发OnClose事件....这就是你得到递归错误的原因。

如果你没有捕获EVT_CLOSE并使用self.Close()它应该工作。如果没有,那通常意味着你有一个计时器,线程或隐藏的顶级窗口,也需要停止或关闭。我希望这是有道理的。