GridBagSizer: Wrong cell size with colspan?

1,151 views
Skip to first unread message

Pyfips

unread,
Jul 10, 2019, 11:58:55 AM7/10/19
to wxPython-users
Hello, I have a problem with the wx.GridBagSizer when aligning items.

This here is my dialog:


import wx


class TestFrameGridBag(wx.Dialog):
   
def __init__(self, parent):
       
super().__init__(parent)
        szr
= wx.GridBagSizer()
       
self.SetMinSize((50, 100))

       
self.btn1 = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, size=(16, 16)))
       
self.btn2 = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, size=(16, 16)))
       
self.btn3 = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, size=(16, 16)))
       
self.btn4 = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, size=(16, 16)))

        szr
.Add(wx.TextCtrl(self), (0, 0), flag=wx.EXPAND)
        szr
.Add(self.btn1, (0, 1))
        szr
.Add(self.btn2, (0, 2))

        szr
.Add(wx.TextCtrl(self), (1, 0), flag=wx.EXPAND)
        szr
.Add(self.btn3, (1, 1))
        szr
.Add(self.btn4, (1, 2))

        pnl
= wx.Panel(self)  # with size=(0, -1) it works like expected
        bszr = wx.BoxSizer(wx.HORIZONTAL)
        bszr
.Add(wx.TextCtrl(pnl), proportion=1, flag=wx.EXPAND)
        bszr
.Add(wx.TextCtrl(pnl), proportion=1, flag=wx.EXPAND)
        pnl
.SetSizer(bszr)

        szr
.Add(pnl, (2, 0), span=(1, 3), flag=wx.EXPAND)  # with span=(1, 1) it works like expected, but it is too short.
        szr.AddGrowableCol(0, 1)

       
self.SetSizer(szr)

app
= wx.App()
dlg
= TestFrameGridBag(None)
dlg
.ShowModal()

And this is what I want to get:

ScreenShot 015 .png

However, this it what I do get:

 ScreenShot 014 .png

To me, it looks like the min size of the right column is calculated wrong.
As a workaround I can do the following things:
  • Wrap the items at the bottom in a panel (as in the code example above), and set the size of this panel to (0, -1). However, if I do this<dlg>.GetSizer().ComputeFittingWindowSize() returns wrong values, since the minimum width of the item at the bottom of the dialog is 0. Min sizes of elements that are wrapped by this panel are ignored. That makes it difficult to me to dynamically calculate the min size of that dialog.
  • Alternatively, I can add more columns: If the elements in the first column have a colspan of 20 (so the buttons are in column 21 and 22), then I have a workaround for this problem too. But this seems very ugly to me too.
Now to my question: Is this a bug or is there any "nice" way to
1) Align the things like in the the first screenshot
2) Be able to calculate a "good" size for elements.

Thank you in advance and best regards


Tim Roberts

unread,
Jul 10, 2019, 7:57:57 PM7/10/19
to 'Pyfips' via wxPython-users
'Pyfips' via wxPython-users wrote:
> Hello, I have a problem with the wx.GridBagSizer when aligning items.
> To me, it looks like the min size of the right column is calculated wrong.

I'm not convinced this can be called a bug.  You have presented the
sizer with a very difficult layout problem here.  How is it supposed to
know what you wanted?  It asks the text boxes what size they want to be,
and makes column 0 that size.   Columns 2 and 3 then follow immediately
thereafter.  The third row, spanning all the columns, can't offer any
help in the layout.  There are simply no clues that column 0 should be
bigger.

If you set "size=(400,-1)" in the two wx.TextCtrls, then it all looks as
you expect, because the text controls force column 0 to be larger.  I
think that's the sensible option.  Beyond that, I don't think there's
any way for the sizer to figure out the layout you want.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.


Pyfips

unread,
Jul 11, 2019, 10:15:39 AM7/11/19
to wxPython-users
Hello Tim,

thank you for your quick answer.
I thought, that self.AddGrowableCol(0, 1) would tell the sizer that the first column should grow in case it is too short (and not the third one).
What I try to achieve is to write a generic dialog, so that the user can write the UI without caring about sizers, border etc. The GridBagSizer seemed ideal to me but that behaviour makes it difficult to keep the solution generic.
Is there alternatively a way how I can recalculate the column sizes of the sizer and set them manually? I could not find any in the help file.

Thank you and best regards

Tim Roberts

unread,
Jul 11, 2019, 7:22:59 PM7/11/19
to wxpytho...@googlegroups.com
'Pyfips' via wxPython-users wrote:
>
> I thought, that self.AddGrowableCol(0, 1) would tell the sizer that
> the first column should grow in case it is too short (and not the
> third one).

Well, yes, but there's no reason to say that the first column is "too
short".  The first column is, in fact, exactly large enough to contain
its contents, as are the second and third columns. That's the problem.  
Having the spanned content doesn't trigger any changes to the individual
columns.


> What I try to achieve is to write a generic dialog, so that the user
> can write the UI without caring about sizers, border etc. The
> GridBagSizer seemed ideal to me but that behaviour makes it difficult
> to keep the solution generic.

Right.  There's really no way to do a "generic" UI, because everyone has
a different idea of what the ideal layout is.  That's why there are so
many different sizers.


> Is there alternatively a way how I can recalculate the column sizes of
> the sizer and set them manually? I could not find any in the help file.

Well, how would YOU, as a human being, decide what needed to be done
here?  It's not at all obvious.  You have an idea in your mind of how it
should look, but what algorithm would you use to induce the grid to
produce that?

Pyfips

unread,
Jul 12, 2019, 2:27:26 AM7/12/19
to wxPython-users
Hi Tim,

I see that it is difficult to figure out the "correct" / wanted sizes by the sizer. Maybe my expectation was wrong; for me it is a bit counter intuitive that the sizer stretches the third column, if I explicitly tell it to stretch the first one. Expecially as it will do so if I resize the dialog, for example.
I will try the size=(0, -1) workaround and see if I can calculate the min size of the dialog with respect to the contents of that panel.

Thank you for your advice!
Reply all
Reply to author
Forward
0 new messages