GridBagSizer layout incorrect when setting MinSize of a cell-widget

Hello,

I am using GridBagSizer with 2 rows and 2 columns. Cell 0/0 contains a button where minsize is increased. Cells 1/0 and 1/1 contain a button with original minsize. Both col 0 an 1 is growable.
When the window is displayed the first time, then the layout looks o.k., but when I make the window larger, then the button in cell 1/1 moves to the left under the button in cell 0/0.

See the sample code in the attachement.
I am using wxPython 2.8.10.1 and Windows-Vista.

Regards,
Erwin

gbsizer.py (711 Bytes)

···

--
GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit
gratis Handy-Flat! http://portal.gmx.net/de/go/dsl

When you set the columns to be growable you used a proportion = 1 for each of them. This causes the cols to always be equal width regardless of what the min size of the items in the col actually are. (The initial layout looks correct because the frame was larger when it was first created, and the Fit before the show is changing things in a way that there isn't an extra size event to do another layout.

Anyway, change the AddGrowable lines like this and it will work the way you are expecting:

         sizer.AddGrowableCol(0)
         sizer.AddGrowableCol(1)

Also, take a look at this: http://wiki.wxpython.org/Widget_Inspection_Tool

···

On 2/1/11 2:23 PM, erny hombre wrote:

Hello,

I am using GridBagSizer with 2 rows and 2 columns. Cell 0/0 contains a button where minsize is increased. Cells 1/0 and 1/1 contain a button with original minsize. Both col 0 an 1 is growable.
When the window is displayed the first time, then the layout looks o.k., but when I make the window larger, then the button in cell 1/1 moves to the left under the button in cell 0/0.

--
Robin Dunn
Software Craftsman

Thank you for your answer.
1)
Omitting proportion works in this case. But what if you want to use
different proportions ? The doc says that AddGrowableCol specifies
that column idx should be grown if there is extra space available to
the sizer. In a special case the column shrinks when little extra
space is available. Example:

import wx
class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "GridBagSizer")
        sizer = wx.GridBagSizer()
        button = wx.Button(self, -1, "0,0")
        sizer.Add(button, pos=(0,0))
        button = wx.Button(self, -1, "0,1")
        sizer.Add(button, pos=(0,1))
        sizer.AddGrowableCol(0, 1)
        sizer.AddGrowableCol(1, 2)
        self.SetSizer(sizer)
        self.Fit()
app = wx.PySimpleApp()
TestFrame().Show()
app.MainLoop()

When the windows width is increased a little bit, then button(0,1)
moves behind button(0,0) because column 1 shrinks.

2)
I did some further experiments with GridBagSizer. Here is another
example where the column sizes are not what I expected:

import wx
class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "GridBagSizer")
        sizer = wx.GridBagSizer()
        button = wx.Button(self, -1, "0,0")
        old_size = button.GetBestSize()
        button.SetMinSize((old_size[0] * 3, old_size[1]))
        sizer.Add(button, pos=(0,0), span=(1,2))
        button = wx.Button(self, -1, "1,0")
        sizer.Add(button, pos=(1,0), flag=wx.EXPAND)
        button = wx.Button(self, -1, "1,1")
        sizer.Add(button, pos=(1,1), flag=wx.EXPAND)
        sizer.AddGrowableCol(0)
        sizer.AddGrowableCol(1)
        self.SetSizer(sizer)
        self.Fit()
app = wx.PySimpleApp()
TestFrame().Show()
app.MainLoop()

Row 0 contains an increased button that spans 2 columns. Result:
button(1,0) and button(1,1) do not have the same width. Is this
correct ?

3)
Not all available extra space is distributed over the growable
columns. You can see this effect when you use more columns. Example:
import wx
class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "GridBagSizer")
        sizer = wx.GridBagSizer()
        for i in range(10):
            button = wx.Button(self, -1, "0,%d" % i)
            sizer.Add(button, pos=(0,i))
            sizer.AddGrowableCol(i)
        self.SetSizer(sizer)
        self.Fit()
app = wx.PySimpleApp()
TestFrame().Show()
app.MainLoop()

When the width of the window is increased by only a few pixels, no
extra space is distributed. Only when you further increase the window
width, then the space is distributed over the columns.

···

On 2 Feb., 02:15, Robin Dunn <ro...@alldunn.com> wrote:

When you set the columns to be growable you used a proportion = 1 for
each of them. This causes the cols to always be equal width regardless
of what the min size of the items in the col actually are.

When you set the columns to be growable you used a proportion = 1 for
each of them. This causes the cols to always be equal width regardless
of what the min size of the items in the col actually are.

Thank you for your answer.
1)
Omitting proportion works in this case. But what if you want to use
different proportions ? The doc says that AddGrowableCol specifies
that column idx should be grown if there is extra space available to
the sizer. In a special case the column shrinks when little extra
space is available. Example:

         sizer.AddGrowableCol(0, 1)
         sizer.AddGrowableCol(1, 2)

When the windows width is increased a little bit, then button(0,1)
moves behind button(0,0) because column 1 shrinks.

So in other words the free space is divided into 3 shares and one share goes to col zero and the other 2 shares go to col 1. In 2.8 this means that col 1 will always try to be twice as large as col 0, and that is what causes the problem you are seeing when there isn't enough space to show the full widget and also honor the 1:2 ratio.

BTW, how proportional items are laid out has been changed in 2.9.2 such that the min/best size of an item is taken into account before the proportions are calculated and it will try to always give all items at least it's min/best size. This it probably more in line with how you were expecting things to work.

2)
I did some further experiments with GridBagSizer. Here is another
example where the column sizes are not what I expected:

         button = wx.Button(self, -1, "0,0")
         old_size = button.GetBestSize()
         button.SetMinSize((old_size[0] * 3, old_size[1]))
         sizer.Add(button, pos=(0,0), span=(1,2))
         button = wx.Button(self, -1, "1,0")
         sizer.Add(button, pos=(1,0), flag=wx.EXPAND)
         button = wx.Button(self, -1, "1,1")
         sizer.Add(button, pos=(1,1), flag=wx.EXPAND)
         sizer.AddGrowableCol(0)
         sizer.AddGrowableCol(1)

Row 0 contains an increased button that spans 2 columns. Result:
button(1,0) and button(1,1) do not have the same width. Is this
correct ?

Yes. In this case the size needed for the first col is effectively calculated only from the 0,1 button because that is the only item that resides only in col 0. That means that because of the button in (0,0) spanning the first 2 columns that the size of the 2nd col must be the button's min width minus the width of col 0, which ends up in this case with the 2nd col being larger than the first. (There's a lot more to it than that, but the simplification should help you understand the kinds of things that go into the GBS layout calculations.)

3)
Not all available extra space is distributed over the growable
columns. You can see this effect when you use more columns. Example:

When the width of the window is increased by only a few pixels, no
extra space is distributed. Only when you further increase the window
width, then the space is distributed over the columns.

This has been fixed in 2.9.

···

On 2/2/11 1:05 PM, ErwinP wrote:

On 2 Feb., 02:15, Robin Dunn<ro...@alldunn.com> wrote:

--
Robin Dunn
Software Craftsman