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()