I tried your first suggestion, but still have issues. Code snippet below.
It seems that the only StaticBoxSizer constructor available in wxPython
relies on creating the StaticBox first and passing it to the constructor.
http://www.wxpython.org/docs/api/wx.StaticBoxSizer-class.html
Unfortunately creating the box adds it to the child of the sized panel,
and other controls are put along side the StaticBox, not inside the
static box.
I'm guessing that the second constructor method in the StaticBoxSizer
wxWidgets documentation would be the way to go. i.e. the constructor
creates the StaticBox.
http://docs.wxwidgets.org/stable/wx_wxstaticboxsizer.html#wxstaticboxsizer
Is this available in wxPython somehow ??
Maybe there is someway I can delete the 'child' but still have the sizer ??
class SBPanel( sc.SizedPanel ):
def __init__( self, parent, id, label='' ):
sc.SizedPanel.__init__( self, parent, id )
box = wx.StaticBox( self, label=label )
box.SetSizerProps( halign='center', expand=True, proportion=1 )
sizer = wx.StaticBoxSizer( box, orient=wx.HORIZONTAL )
self._SetNewSizer( sizer )
b1 = wx.Button(self, -1, 'b1')
t1 = wx.TextCtrl(self, -1, 't1')
b2 = wx.Button(self, -1, 'b2')
self.Fit()
self.SetMinSize( self.GetSize() )
>> This is untested but looking at the code it looks like you can set the
>> sizer type to "horizontal" or "vertical" to get a standard box sizer,
>> and then replace it with a wx.StatiBoxSizer with a call to _SetNewSizer.
>>
>> The other option would be to teach SetSizerType to be able to create and
>> use wx.StaticBoxSizers on its own, and submit a patch.
>
>
> I tried your first suggestion, but still have issues. Code snippet below.
>
> Unfortunately creating the box adds it to the child of the sized panel,
> and other controls are put along side the StaticBox, not inside the
> static box.
>
> Maybe there is someway I can delete the 'child' but still have the sizer ??
I got it to work by overriding the _SetNewSizer() method, so that it
didn't add the StaticBox control to the sizer :)
Only problem now is I get a segmentaion fault when exiting the program :(
I'm guessing that the StaticBox is being destroyed while the sizer is
still in use -- or something of that nature ???
Any ideas where to go from here so that it exits cleanly ???
class SBPanel( sc.SizedPanel ):
def __init__( self, parent, id, label = 'SBPanel' ):
sc.SizedPanel.__init__( self, parent, id )
box = wx.StaticBox( self, label = label )
box.SetSizerProps( halign='center', expand=True, proportion=1 )
self.boxId = box.GetId()
sizer = wx.StaticBoxSizer( box, orient = wx.HORIZONTAL )
self._SetNewSizer( sizer )
b1 = wx.Button(self, -1, 'b1')
t1 = wx.TextCtrl(self, -1, 't1')
b2 = wx.Button(self, -1, 'b2')
self.Fit()
self.SetMinSize( self.GetSize() )
def _SetNewSizer(self, sizer):
props = {}
for child in self.GetChildren():
childId = child.GetId()
props[childId] = child.GetSizerProps()
self.GetSizer().Detach(child)
wx.PyPanel.SetSizer(self, sizer)
for child in self.GetChildren():
childId = child.GetId()
if childId != self.boxId :
self.GetSizer().Add(child)
child.SetSizerProps(props[childId])
Ah, I forgot that the AddChild method is doing that magic behind the
scenes... I think that the way I would handle this is to override
AddChild and tweak it such that when it is being called for the
staticbox that will be used for the sizer then just call
wx.PyPanel.AddChild directly, otherwise call SizedPanel.AddChild so it
will add the child to the sizer.
>
> I'm guessing that the second constructor method in the StaticBoxSizer
> wxWidgets documentation would be the way to go. i.e. the constructor
> creates the StaticBox.
>
> http://docs.wxwidgets.org/stable/wx_wxstaticboxsizer.html#wxstaticboxsizer
>
> Is this available in wxPython somehow ??
No, but it would have the same problem even if it was available. It
still needs to create a staticbox widget as a child of the panel, and
when it does the panel's AddChild will still be called.
--
Robin Dunn
Software Craftsman
http://wxPython.org
There is probably something that is still referring to the old sizer and
is trying to destroy it a 2nd time at shutdown.
The following solves the segfault on closing the application.
Basically create the static box, and then detach it from the 'original'
sizer immediately.
box = wx.StaticBox( self, label = label )
self.GetSizer().Detach(box)
Also put in additional check in _SetNewSizer() to not detach the static
box child (as it isn't attached anymore).
Of course the "proper" way to do this is to modify the SetSizerType()
method in SizedPanel and submit a patch. I will work on that :)
import wx
import wx.lib.sized_controls as wxSC
class SBPanel( wxSC.SizedPanel ):
def __init__( self, parent, id, label = '' ):
wxSC.SizedPanel.__init__( self, parent, id )
self.SetSizerType( type = 'staticbox', label = label )
#b1 = wx.Button( self, wx.ID_ANY, 'b1' )
#t1 = wx.TextCtrl( self, wx.ID_ANY, 't1' )
#b2 = wx.Button( self, wx.ID_ANY, 'b2' )
self.Fit()
self.SetMinSize( self.GetSize() )
def SetSizerType( self, type, label ):
"Override method in SizedPanel to support StaticBoxSizer."
box = wx.StaticBox( self, label = label )
# Detach staticBox from the original sizer to avoid
# segfault on destruction.
self.GetSizer().Detach(box)
self.boxId = box.GetId()
sizer = wx.StaticBoxSizer( box, orient = wx.HORIZONTAL )
self._SetNewSizer( sizer )
def _SetNewSizer(self, sizer):
"Override method in SizedPanel to support StaticBoxSizer."
wxSC.SizedPanel.sizerType = sizer
props = {}
for child in self.GetChildren():
childId = child.GetId()
if childId != self.boxId :