Nested sizers

All,

What happens with wx.EXPAND when sizers are nested? Consider:

        wred = ColWin(self, wx.ID_ANY, wx.RED)
        wwhite = ColWin(self, wx.ID_ANY, wx.WHITE)
        
        h = 40
        b1 = wx.Button(self, wx.ID_ANY, '1', wx.DefaultPosition, (-1, h))
        b2 = wx.Button(self, wx.ID_ANY, '2', wx.DefaultPosition, (-1, h))
        b3 = wx.Button(self, wx.ID_ANY, '3', wx.DefaultPosition, (-1, h))
        b4 = wx.Button(self, wx.ID_ANY, '4', wx.DefaultPosition, (-1, h))
        b5 = wx.Button(self, wx.ID_ANY, '', wx.DefaultPosition, (-1, h))
        b5.Enable(False)
        
        hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
        b = 0
        f = wx.ALL
        hsizer1.Add(b1, 0, f, border=b)
        hsizer1.Add(b2, 0, f, border=b)
        hsizer1.Add(b3, 0, f, border=b)
        hsizer1.Add(b4, 0, f, border=b)
        hsizer1.Add(b5, 1, f, border=b)
        
        b = 2
        hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
        hsizer2.Add(wred, 1, wx.EXPAND | wx.RIGHT, b)
        hsizer2.Add(wwhite, 1, wx.EXPAND | wx.LEFT, b)
        
        b = 5
        vsizer1 = wx.BoxSizer(wx.VERTICAL)
        vsizer1.Add(hsizer1, 0, wx.EXPAND | wx.RIGHT, b)
        vsizer1.Add(hsizer2, 1, wx.EXPAND | wx.ALL, b)
        
        self.SetSizer(vsizer1)

Why do I need these:

       vsizer1.Add(hsizer1, 0, wx.EXPAND | wx.RIGHT, b)
        vsizer1.Add(hsizer2, 1, wx.EXPAND | wx.ALL, b)

To allow these to expand horizontally:

        hsizer2.Add(wred, 1, wx.EXPAND | wx.RIGHT, b)
        hsizer2.Add(wwhite, 1, wx.EXPAND | wx.LEFT, b)

Can anyone summarize what to expect regarding wx.EXPAND when sizers are nested?

Thanks.

David.

A nested sizer is just another kind of item that can be added to a sizer, and it will follow the exact same rules as adding a widget to a sizer. Just think of a sizer item as a rectangle on screen that the sizer will manipulate based on the args passed to Add() and on what the item's min/best size is. When the parent sizer calculates what space to give an item then items that are widgets are positioned and sized to that space and items that are sizers will recursively do a Layout() within the space they are given.

···

On 4/5/10 11:23 PM, David Arnold wrote:

All,

What happens with wx.EXPAND when sizers are nested?

--
Robin Dunn
Software Craftsman

Robin,

All,

What happens with wx.EXPAND when sizers are nested?

A nested sizer is just another kind of item that can be added to a sizer, and it will follow the exact same rules as adding a widget to a sizer. Just think of a sizer item as a rectangle on screen that the sizer will manipulate based on the args passed to Add() and on what the item's min/best size is. When the parent sizer calculates what space to give an item then items that are widgets are positioned and sized to that space and items that are sizers will recursively do a Layout() within the space they are given.

OK, but here is what I don't understand. Consider:

class MyPanel10(wx.Panel):
    
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        
        wred = ColWin(self, wx.ID_ANY, wx.RED)
        wwhite = ColWin(self, wx.ID_ANY, wx.WHITE)
        
        h = 40
        b1 = wx.Button(self, wx.ID_ANY, '1', wx.DefaultPosition, (-1, h))
        b2 = wx.Button(self, wx.ID_ANY, '2', wx.DefaultPosition, (-1, h))
        b3 = wx.Button(self, wx.ID_ANY, '3', wx.DefaultPosition, (-1, h))
        b4 = wx.Button(self, wx.ID_ANY, '4', wx.DefaultPosition, (-1, h))
        b5 = wx.Button(self, wx.ID_ANY, '', wx.DefaultPosition, (-1, h))
        b5.Enable(False)
        
        hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
        b = 0
        f = wx.ALL
        hsizer1.Add(b1, 0, f, border=b)
        hsizer1.Add(b2, 0, f, border=b)
        hsizer1.Add(b3, 0, f, border=b)
        hsizer1.Add(b4, 0, f, border=b)
        hsizer1.Add(b5, 1, f, border=b)
        
        b = 2
        hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
        hsizer2.Add(wred, 1, wx.EXPAND | wx.RIGHT, b)
        hsizer2.Add(wwhite, 1, wx.EXPAND | wx.LEFT, b)
        
        b = 5
        vsizer1 = wx.BoxSizer(wx.VERTICAL)
        vsizer1.Add(hsizer1, 0, wx.RIGHT, b)
        vsizer1.Add(hsizer2, 1, wx.ALL, b)
        
        self.SetSizer(hsizer2)

This code eventually results in the attached Figure1.png. As you can see, the red and white panels stretch horizontally. This I understand.

Now, if I change the last line to setSizer(vsizer1), I get Figure2.png. What I don't understand is why I no longer have what I had in Figure1.png.

Finally, if I change the last three lines, adding wx.EXPAND's:

        vsizer1.Add(hsizer1, 0, wx.EXPAND|wx.RIGHT, b)
        vsizer1.Add(hsizer2, 1, wx.EXPAND|wx.ALL, b)
        
        self.SetSizer(vsizer1)

Now my red and white panels have returned in Figure3.png. Why do I need the extra wx.EXPAND's in the third case when I already had the expanded red and white panels in the first case?

David.

.

Because that just tells hsizer2 to expand wred and wwhite to expand to fill the space given to hsizer2. Since the best size of those panels is (0,0) then hsizer2's min size is (0,0) and that is all the width that it will be given by vsizer1. So by telling vsizer1 to EXPAND hsizer2 then it will be told to use the whole width of vsizer1, and then hsizer2 will then use the full width in its layout calculations and because of the proportion=1 parameters for wred and wwhite then hsizer2 will split the available horizontal space between them. The wx.EXPAND flags on wred and wwhite cause them to be expanded vertically since they are in a horizontal sizer.

···

On 4/6/10 9:33 AM, David Arnold wrote:

Finally, if I change the last three lines, adding wx.EXPAND's:

         vsizer1.Add(hsizer1, 0, wx.EXPAND|wx.RIGHT, b)
         vsizer1.Add(hsizer2, 1, wx.EXPAND|wx.ALL, b)

         self.SetSizer(vsizer1)

Now my red and white panels have returned in Figure3.png. Why do I need the extra wx.EXPAND's in the third case when I already had the expanded red and white panels in the first case?

--
Robin Dunn
Software Craftsman

Robin,

Thanks. Your explanations are helping.

D.

···

On Apr 6, 2010, at 10:34 AM, Robin Dunn wrote:

On 4/6/10 9:33 AM, David Arnold wrote:

Finally, if I change the last three lines, adding wx.EXPAND's:

        vsizer1.Add(hsizer1, 0, wx.EXPAND|wx.RIGHT, b)
        vsizer1.Add(hsizer2, 1, wx.EXPAND|wx.ALL, b)

        self.SetSizer(vsizer1)

Now my red and white panels have returned in Figure3.png. Why do I need the extra wx.EXPAND's in the third case when I already had the expanded red and white panels in the first case?

Because that just tells hsizer2 to expand wred and wwhite to expand to fill the space given to hsizer2. Since the best size of those panels is (0,0) then hsizer2's min size is (0,0) and that is all the width that it will be given by vsizer1. So by telling vsizer1 to EXPAND hsizer2 then it will be told to use the whole width of vsizer1, and then hsizer2 will then use the full width in its layout calculations and because of the proportion=1 parameters for wred and wwhite then hsizer2 will split the available horizontal space between them. The wx.EXPAND flags on wred and wwhite cause them to be expanded vertically since they are in a horizontal sizer.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

To unsubscribe, reply using "remove me" as the subject.