pythonwxpythonsizer

wxpython sizers - does WX.EXPAND make a difference in spacers?


Following good advice in the BoxSizer from the ground Up tutorial I am refactoring code to factor out the wx.LEFT/RIGHT/TOP/BOTTOM flags into "spacers" - so:

horizontal_sizer.Add(someControl, 0, wx.LEFT, border)

becomes:

horizontal_sizer.Add((border, 0))
horizontal_sizer.Add(someControl)

For the case above I am sure they are completely equivalent. However if wx.EXPAND and a non zero proportion is specified as in:

horizontal_sizer.Add(someControl, proportion, wx.LEFT | wx.EXPAND, border)

is this below:

horizontal_sizer.Add((border, 0))
horizontal_sizer.Add(someControl, proportion, wx.EXPAND)

completely equivalent to the above ? Visually they do seem identical but is there anything I am missing ? In other words does the wx.EXPAND influence the border and if yes how ?

Of course the examples above are trivial but in complex sizers layouts the above transformation (as suggested in the tutorial) greatly simplifies the code and makes common UI patterns stand out, that were plain unreadable in the mess of OR'ed flags and numbers.

EDIT: feedback on the Right Way to add a spacer would be appreciated. For instance I saw here:

mainSizer.Add(wx.StaticText(self), 0, wx.EXPAND)  # add a "spacer"

or in the code I maintain people do:

horizontal_sizer.Add((0, 0), 1) # which seems equivalent to Add((0, 0))

Now in python there should be one-- and preferably only one --obvious way to do it - here there are at least 4 - so some expert feedback appreciated.


Solution

  • Yes, proportion values and the wx.EXPAND flag are applied to spacers the same as for widgets. The item's minsize should be the size it was given when adding the spacer, (instead of being a property of the widget like usual.) You can easily implement some nicely resizing layouts with expandable sizers.

    Using a wx.StaticText as a spacer works, but seems wasteful to me as there is no need to have a widget there, unless you need to do something special with it like setting a label at a later time or something like that. I definitely would not call it a spacer though, it is a widget that happens to be blank at the moment.

    Some of the more-than-one-way to do it came from a slight evolution of the C++ API over time, and wanting to maintain backwards compatibility, and also a bit of pythonization for the wrappers. However it is less messy than it was for a while, and the good news is that it is well documented in the Phoenix docs. What is documented there should be compatible with Classic, and will continue to work with Phoenix into the future.

    https://wxpython.org/Phoenix/docs/html/wx.Sizer.html

    BTW, you didn't mention the convenience methods AddSpacer and AddStretchSpacer, so add another way to do it to the list. ;-) They do help with disambiguation however, so that is a nice addition.