The script below crashes Python on OS X (EPD 7.0-2 & 7.1.2) when the
ComboBox is used. Similar code would also crash python on Windows as
well, but somehow in the process of reducing this from a ~10,000
program to a ~100 line example, the Windows problem went away.
The code reconfigures the contents of a ScrolledWindow. Since on OS X,
the ScrolledWindow will have scrollbars as children, a panel is placed
inside the ScrolledWindow and I use various methods to clear that out,
so that I can place new stuff inside (see comments), but nothing I I
have tried works properly. Is there some extra step that is needed to
safely destroy widgets?
Brian
···
#================================================================
import wx
def OnSizeType(event):
w = event.GetEventObject()
topframe =
w.GetParent().GetParent().GetParent().GetParent().GetParent()
topframe.Mode = w.GetValue()
updateDataPanel(topframe)
def updateDataPanel(topframe):
def TopSizer(topframe):
topSizer = wx.BoxSizer(wx.HORIZONTAL)
sizeType = wx.ComboBox(topframe.dataPanel,wx.ID_ANY,
value=topframe.Mode,
choices=['isotropic','ellipsoidal'],
style=wx.CB_READONLY|wx.CB_DROPDOWN)
sizeType.Bind(wx.EVT_COMBOBOX, OnSizeType)
topSizer.Add(sizeType)
return topSizer
def IsoSizer(topframe):
isoSizer = wx.BoxSizer(wx.HORIZONTAL)
sizeVal = wx.TextCtrl(topframe.dataPanel,wx.ID_ANY,
'1.1',style=wx.TE_PROCESS_ENTER)
isoSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
return isoSizer
def EllSizeDataSizer(topframe):
dataSizer = wx.FlexGridSizer(1,6,5,5)
for Pa,val,ref in zip(['S11','S22','S33','S12','S13','S23'],
[5.0,5.1,5.2,5.3,5.4,5.5],
[True,] + 5*[False,]):
sizeVal = wx.TextCtrl(topframe.dataPanel,wx.ID_ANY,'%.3f'%
(val),
style=wx.TE_PROCESS_ENTER)
dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL)
return dataSizer
if topframe.dataPanel is None:
topframe.dataPanel = wx.Panel(topframe.dataScroll)
else:
# cleanup attempt #1 -- delete sizer contents. Crashes python
on OS X
topframe.dataPanel.GetSizer().Clear(True)
# cleanup attempt #2 -- delete panel's children. Crashes
python on OS X
#topframe.dataPanel.DestroyChildren()
# cleanup attempt #3 -- delete panel. Crashes python on OS X
#topframe.dataPanel.Destroy()
#topframe.dataPanel = wx.Panel(topframe.dataScroll)
# cleanup attempt #4 -- remove sizer contents. Windows remain
#topframe.dataPanel.GetSizer().Clear()
# cleanup attempt #5 -- do nothing here but use deleteOld
option on SetSizer
# children are not shown, but keep piling up
#print 'Panel child
count:',len(topframe.dataPanel.GetChildren())
mainSizer = wx.BoxSizer(wx.VERTICAL)
if topframe.Mode == 'isotropic':
isoSizer = wx.BoxSizer(wx.HORIZONTAL)
isoSizer.Add(TopSizer(topframe),0,wx.ALIGN_CENTER_VERTICAL)
isoSizer.Add(IsoSizer(topframe),0,wx.ALIGN_CENTER_VERTICAL)
mainSizer.Add(isoSizer)
elif topframe.Mode == 'ellipsoidal':
ellSizer = wx.BoxSizer(wx.HORIZONTAL)
ellSizer.Add(TopSizer(topframe),0,wx.ALIGN_CENTER_VERTICAL)
mainSizer.Add(ellSizer)
mainSizer.Add(EllSizeDataSizer(topframe))
#topframe.dataPanel.SetSizer(mainSizer,deleteOld=True)
topframe.dataPanel.SetSizer(mainSizer)
mainSizer.Fit(topframe.childFrame)
Size = mainSizer.GetMinSize()
Size[0] += 40
Size[1] = max(Size[1],250) + 20
topframe.dataPanel.SetSize(Size)
topframe.dataScroll.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
Size[1] = min(Size[1],450)
topframe.childFrame.setSizePosLeft(Size)
def UpdatePhaseData(topframe):
topframe.dataScroll = wx.ScrolledWindow(topframe.childNB)
topframe.childNB.AddPage(topframe.dataScroll,'Data')
Texture = wx.ScrolledWindow(topframe.childNB)
topframe.childNB.AddPage(Texture,'Texture')
updateDataPanel(topframe)
class ChildFrame(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent=parent,
style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX)
self.Show()
def setSizePosLeft(self,Width):
clientSize = wx.ClientDisplayRect()
Width[1] = min(Width[1],clientSize[2]-300)
Width[0] = max(Width[0],300)
self.SetSize(Width)
self.SetPosition(wx.Point(clientSize[2]-
Width[0],clientSize[1]+250))
class GSNoteBook(wx.Notebook):
def __init__(self, parent):
wx.Notebook.__init__(self, parent, -1, name='', style=
wx.BK_TOP)
self.SetSize(parent.GetClientSize())
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title = u'Main window')
self.childFrame = ChildFrame(parent=self)
self.childFrame.SetMenuBar(wx.MenuBar())
self.childFrame.SetLabel('Child Frame')
self.childFrame.CreateStatusBar()
self.childNB = GSNoteBook(parent=self.childFrame)
self.dataScroll = None
self.dataPanel = None
self.Mode = 'isotropic'
UpdatePhaseData(self)
if __name__ == '__main__':
import sys
app = wx.PySimpleApp()
frame = MyFrame()
frame.Show(True)
app.MainLoop()