wxPython, создающий новые wxFrames и закрывающий их, замораживает Python

Я пытаюсь создать wxFrames по нажатию на кнопку из TopWindow приложения wx. Несмотря на то, что создаются экземпляры фреймов, и я ясно вижу их, когда я закрываю приложение (дочерний фрейм), возникает несколько вопросов:

Несколько проблем

  • Я не могу открыть тот же кадр снова. Я ничего не создаю, поэтому не знаю, почему это будет ошибкой.
  • Я не могу закрыть родительский фрейм в один клик. Родительский фрейм сначала удаляет все его дочерние элементы в приложении, а затем мне нужно было бы нажать красную кнопку x еще раз, чтобы закрыть его.
  • После закрытия родительского фрейма я не могу открыть другой экземпляр из своей IDE(я использую Enthought Canopy). Я должен был бы перезапустить экземпляр Python, а затем обновить.

Иллюстрация 2-й проблемы

Вот иллюстрация глючного родительского кадра:

Перед нажатием кнопки закрытия

После нажатия кнопки закрытия

Я не понимаю, почему это происходит. Вот мой код:

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 ответ

Я думаю, что это о воспитании подкадров. Все кадры созданы, но изначально они не видны. Если они никогда не показываются, их невозможно уничтожить, если у них нет родителей. Основной цикл будет работать вечно. Попробуйте этот минимальный пример:

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()
Другие вопросы по тегам