how to add to sizer AFTER frame initialized

Hello,

I can't find the solution to this, I've searched with Google etc: Could
someone explain what methods should be called *after* the GUI has been
initialized (all sizers created etc), and items are added/removed from a
sizer as a consequence of the user doing something?

E.g., in the following code, creating AppFrame with testGood=False leads to
bad layout, whereas with testGood=true it gives correct layout. I suspect is
has to do with sizer min size, but I've tried all sorts of combinations of
Layout(), Fit(), SetSizeHints() and nothing works. Here is the 100 LOC:

from wxPython.wx import *

class PanelSegments(wxPanel):

    def _init_sizers(self):
        self.rootSizer = wxBoxSizer(orient=wxVERTICAL)
        self.mainBoxSizer = wxStaticBoxSizer(box=self.boxMain,
orient=wxVERTICAL)
        self.gridSizerMain = wxFlexGridSizer(cols=2, hgap=5, rows=0, vgap=5)

        flag = wxALL | wxALIGN_CENTER | wxGROW
        parent = self.gridSizerMain
        parent.AddWindow(self.labelNumSign, 0, border=0, flag=flag)
        parent.AddWindow(self.labelLength, 0, border=0, flag=flag)
        parent.AddWindow(self.labelTotal, 0, border=0, flag=flag)
        parent.AddWindow(self.textCtrlTotalL, 0, border=0, flag=flag)
              
        parent.AddGrowableCol(0)
        parent.AddGrowableCol(1)
        
        parent = self.mainBoxSizer
        parent.AddSizer(self.gridSizerMain, 0, border=5, flag=wxALL |
wxGROW)
        parent = self.rootSizer
        parent.AddSizer(self.mainBoxSizer, 0, border=0, flag=wxALL |
wxGROW)
        
        self.SetSizer(self.rootSizer)

    def __init__(self, prnt, id, pos, size, style, name):
        wxPanel.__init__(self, id=wxNewId(), name='PanelSegments',
              parent=prnt, pos=wxPoint(841, 324), size=wxSize(161, 101),
              style=wxTAB_TRAVERSAL)
        self.SetClientSize(wxSize(153, 73))
        self.SetAutoLayout(True)

        self.boxMain = wxStaticBox(id=wxNewId(),
              label='Segments', name='boxMain', parent=self, pos=wxPoint(0,
0),
              size=wxSize(153, 69), style=0)

        self.labelNumSign = wxStaticText(id=wxNewId(),
              label='#', name='labelNumSign', parent=self, pos=wxPoint(10,
18),
              size=wxSize(58, 13), style=0)

        self.labelLength = wxStaticText(id=wxNewId(),
              label='L (mm)', name='labelLength', parent=self,
pos=wxPoint(73,
              18), size=wxSize(69, 13), style=0)

        self.labelTotal = wxStaticText(id=wxNewId(),
              label='Total', name='labelTotal', parent=self, pos=wxPoint(10,
              36), size=wxSize(58, 23), style=0)

        self.textCtrlTotalL = wxTextCtrl(id=wxNewId(),
              name='textCtrlTotalL', parent=self, pos=wxPoint(73, 36),
              size=wxSize(69, 23), style=0, value='')

        self._init_sizers()

    def pushItem(self):
        labelSeg = wxStaticText(id=wxNewId(), label='L1',
              name='N1', parent=self, size=wxSize(6, 13), style=0)
        textCtrlSegL = wxTextCtrl(id=wxNewId(), name='T1',
              parent=self, size=wxSize(31, 23), style=0, value='')

        flag = wxALL | wxGROW | wxALIGN_CENTER
        parent = self.gridSizerMain
        parent.AddWindow(labelSeg, 0, border=0, flag=flag)
        parent.AddWindow(textCtrlSegL, 0, border=0, flag=flag)
        parent.Layout() # ***
        parent.SetSizeHints(self) # ***
        parent.CalcMin() # ***
        
        self.rootSizer.Fit(self)

if __name__ == '__main__':
    class AppFrame(wxFrame):
        def __init__(self, testGood):
            wxFrame.__init__(self, id=wxNewId(), name='AppFrame',
parent=None,
                  pos=wxPoint(369, 254), size=wxSize(200, 300),
                  style=wxDEFAULT_FRAME_STYLE, title='Test')

            self.boxMain = wxStaticBox(id=wxNewId(),
              label='Test', name='boxMain', parent=self, pos=wxPoint(0, 0),
              size=wxSize(153, 69), style=0)
              
            # now create the special panels
            self.panel1 = PanelSegments(self, None, None, None, None, None)
            self.panel2 = PanelSegments(self, None, None, None, None, None)
            if testGood: # add two rows BEFORE initing the sizers
                self.panel1.pushItem()
                self.panel1.pushItem()
              
            # layout
            self.mainSizer = wxBoxSizer(orient=wxVERTICAL)
            self.boxSizer = wxStaticBoxSizer(box=self.boxMain,
orient=wxVERTICAL)
            self.boxSizer.AddWindow(self.panel1, 0, border=0, flag=wxGROW |
wxALL)
            self.boxSizer.AddWindow(self.panel2, 0, border=0, flag=wxGROW |
wxALL)
            self.mainSizer.AddSizer(self.boxSizer, 0, flag=wxGROW | wxALL)
            self.SetSizer(self.mainSizer)
            self.SetAutoLayout(True)
        
            if not testGood: # add two rows AFTER initing the sizers
                self.panel1.pushItem()
                self.panel1.pushItem()
                # use sizer stuff to layout
            
    # run test
    app = wxPySimpleApp()
    dlg = AppFrame(testGood=False)
    dlg.Show()
    app.MainLoop()

Schoenborn, Oliver wrote:

Hello,

I can't find the solution to this, I've searched with Google etc: Could
someone explain what methods should be called *after* the GUI has been
initialized (all sizers created etc), and items are added/removed from a
sizer as a consequence of the user doing something?

E.g., in the following code, creating AppFrame with testGood=False leads to
bad layout, whereas with testGood=true it gives correct layout. I suspect is
has to do with sizer min size, but I've tried all sorts of combinations of
Layout(), Fit(), SetSizeHints() and nothing works. Here is the 100 LOC:

[Please use attachements so the code is not word-wrapped by the mailer, also always mention the platform and version of wxPython used.]

                          # layout
            self.mainSizer = wxBoxSizer(orient=wxVERTICAL)
            self.boxSizer = wxStaticBoxSizer(box=self.boxMain,
orient=wxVERTICAL)
            self.boxSizer.AddWindow(self.panel1, 0, border=0, flag=wxGROW |
wxALL)

Add wxADJUST_MINSIZE flag here. That tells the sizer to ask the window what it's best size is everytime Layout is called, instead of always using the initial or minimum size.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!