Chuck Esterbrook wrote:
I fixed a sizer problem I was having with a button, but don't understand why it didn't work in the first place.
If I add the button like so:
sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL)
Then one row of pixels from the top and bottom each are missing. You can see this here:
http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/button-bad.png
But if I add like this:
sizer.Add(button, 0, wxALIGN_CENTER_VERTICAL|wxGROW)
Then I can see the whole button. See here:
http://chuckesterbrook.com/files/python/wx/problems/button-squeeze/button-good.png
Platform is wxPython 2407, Python 222, Mandrake 9. Code attached.
Why did I have to add wxGROW to make the whole button appear? (wxEXPAND works as well)
I *think* the following should hold true:
* sizers should respect the minimum size of a control
* buttons should report a minimum size that includes their decorative
outline, regardless of what flags were used to add to the sizer
So is this a bug, or am I missing something?
Sort of, and yes.
First of all, the sizers don't clip the windows they contain, they only resize them. If you resized the button to be smaller than it's best size then it would just draw itself smaller. The true minimum size is a lot smaller than what you show in your screen shots.
Sizers use either the default size of a control, (the size it had when it was Add()ed to the sizer) or if the flag wxADJUST_MINSIZE is given then it calls the control's GetBestSize at every Layout() and uses that as the item's min size.
So in your example the problem is not that the sizer isn't allowing the button to draw itself, it's that the default size of the panel the button is on is (20,20) or something like that. So when topPanel is added to the outer sizer that sizer treats the min size of the topPanel as 20 pixels high and so it never makes it any bigger. So it is the topPanel that is clipping the button, (set its background color and it becomes obvious.) Adding a call to sizer.Fit(topPanel) enlarges the panel to be big enough for its sizer's min size, and then that will be the panel's min size in the sizer it is added too. (Lost yet? ) I'm not totally sure what about adding the wxGROW causes it to do the right thing, probably an extra iteration through the sizer algorithm or something.
The default DoGetBestSize for wxWindow will use the sizer if it has one to calculate the window's best size based on the min size of all the sizer items. So another way (and perhaps the best way) to solve this problem is to use the wxADJUST_MINSIZE flag when adding the panel to the outersizer, then the panel's sizer will get used to calculate the layout for all of the components.
The underlying issue here is that sizer calculations are normally only recursive if the item is a nested sizer, not if the item is a window. Adding the wxADJUST_MINSIZE flag for a window that has its own sizer allows the layout calc to cross that boundary and be recursive down through the sizer that belongs to the window item too.
···
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!