wxPython实例化新的wxFrame并关闭它们会冻结Python

时间:2015-09-14 18:30:33

标签: python thread-safety wxpython canopy

我正在尝试通过点击wx应用程序的TopWindow上的按钮来创建wxFrame。即使框架被实例化,我可以清楚地看到它们,当我关闭应用程序(子框架)时,会出现一些问题:

几个问题

  • 我无法再次打开同一帧。我没有实例化任何东西,所以我不知道为什么会出错。
  • 我无法一键关闭父框架。父框架首先删除应用程序中的所有子项,然后我将再次单击红色x按钮关闭它。
  • 关闭父框架后,我无法从IDE中打开另一个实例(我正在使用Enthought Canopy)。我将不得不重新启动python实例然后刷新。

第二个问题的插图

以下是毛刺父框架的图示:

在单击关闭按钮

之前

enter image description here

单击关闭按钮

enter image description here

我不明白为什么会发生这种情况。这是我的代码:

class AppManager(wx.Frame):
    CHOICES = {}
    def __init__(self, parent):
        # build a frame
        wx.Frame.__init__(self, parent, wx.ID_ANY, "Image Calculator", size = (700, 170), style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)
        frameSize = wx.DisplaySize()
        print frameSize
        self.CHOICES = {"ImageCalc2Beta": imageCalc(parent = None), 
        ... More wxFrames ...
        "DarkNoiseGrapherV3": DarkNoiseGrapherv3_Unstable(None, frameSize)}
        # build a panelz
    self.mainPanel = wx.Panel(self, wx.ID_ANY)

    # sizer
    self.buttonSizer = wx.GridSizer(4,0)
    # build buttons for selecting files ==================================================
    self.imageCalc2Beta = wx.Button(self.mainPanel, id=wx.ID_ANY, label = "Open ImageCalc2Beta")
    self.imageCalc2Beta.name = "ImageCalc2Beta"
    self.imageCalc2Beta.Bind(wx.EVT_BUTTON, self.openApp)
    ... more buttons binding to the event ...
    self.DarkNoiseGrapherV3 = wx.Button(self.mainPanel, id=wx.ID_ANY, label = "Open DarkNoiseGrapherV3")
    self.DarkNoiseGrapherV3.name = "DarkNoiseGrapherV3"
    self.DarkNoiseGrapherV3.Bind(wx.EVT_BUTTON, self.openApp)

    #adding buttons into sizer
    self.buttonSizer.Add(self.imageCalc2Beta)

    self.buttonSizer.Add(self.DarkNoiseGrapherV3)  

    #Setting sizer to panel
    self.mainPanel.SetSizer(self.buttonSizer)
    ... more adding buttons ...
    self.mainPanel.Layout()

    def openApp(self, event):
        self.frame = self.CHOICES[event.GetEventObject().name]
        self.frame.Show()

# below is needed for all GUIs
if __name__== '__main__':
    app = wx.App(False) # application object (inner workings) 
    frame = AppManager(parent = None) # frame object (what user sees)
    frame.Show() # show frame
    app.MainLoop() # run main loop  

请注意,字典中的每个wxFrame子项都是独立工作的。我只是想创建一个应用程序来将它们合并在一起。

注意:我尝试使用虚拟wx.Frame执行此操作,但无法复制错误,因此我猜测它可能是我的其他wx.Frame应用程序实现的一部分。但是,我不知道要显示哪些代码部分。

1 个答案:

答案 0 :(得分:0)

我认为这是关于子帧的父母。创建所有帧,butr它们最初是不可见的。如果他们从未被展示过,如果他们没有父母,就无法摧毁他们。主循环将永远运行。试试这个最小的例子:

import wx

class app_frm(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)

        self.choices = {}
        # append frames
        self.choices['parent'] = wx.Frame(self, -1, 'I have parent')
        # try play around with the following two parenting option
        # see difference, when prent is None and the frame is never ``.Show()``n
        prent = self
        #prent = None
        self.choices['noparent'] = wx.Frame(prent, -1, 'I have no parent')

        self.key_map = {}
        pnl = wx.Panel(self, -1)
        sz = wx.BoxSizer(wx.VERTICAL)
        for frm_nm, frm in self.choices.iteritems():
            btn = wx.Button(pnl, -1, 'Show frame {0}'.format(frm_nm))
            btn.Bind(wx.EVT_BUTTON, self.on_btn)
            self.key_map[btn.GetId()] = frm
            sz.Add(btn, 0, wx.EXPAND|wx.ALL, 4)
        pnl.SetSizer(sz)
        sz.Fit(self)

    def on_btn(self, evt):
        btnid = evt.GetId()
        frm = self.key_map[btnid]
        print 'EVT_BUTTON', btnid, frm
        frm.Show()

app = wx.App(redirect=False)
frm_parent = app_frm(None, -1, 'I am parent')
frm_parent.Show()

app.MainLoop()