## How do sizers manage the size and alignment of their children

When a new item is added to a sizer, the sizer uses either the initial size of the item, or the item's best size if there is no initial size set, in its layout calculations. In other words, the sizer does not adjust the size of an item until the sizer is asked to, usually in the context of a window being resized.

When the sizer parent widget is resized, the sizer needs to change the size of its components in response. By default, the sizer keeps the widget aligned to the top and left of its assigned space in the layoutâ€”although the exact specifics of what is considered to be its assigned space vary from sizer to sizer.

You can adjust the resize behavior of a specific widget by assigning specific values to the flag parameter when you add the widget to the sizer. Figure 11.4 shows the result of several different flags applied to the basic grid sizer example, after a user makes the window larger.

Figure 11.4

A grid with resizing widgets

Figure 11.4

### A grid with resizing widgets

Listing 11.3 shows the code used to generate figure 11.4. It is identical to the previous listing, except for the addition of a dictionary of flag values to be applied to the widgets as they are added. These values are shown in bold font.

Listing 11.3 A grid sizer with flags for aligment and sizing import wx from blockwindow import BlockWindow labels = "one two three four five six seven eight nine".split() flags = {"one": wx.ALIGN_BOTTOM, "two": wx.ALIGN_CENTER,

"four": wx.ALIGN_RIGHT, "six": wx.EXPAND, "seven": wx.EXPAND,

"eight": wx_SHAPED} Align ment flags 1

class TestFrame(wx.Frame):

wx.Frame._init_(self, None, -1, "GridSizer Resizing")

sizer = wx.GridSizer(rows=3, cols=3, hgap=5, vgap=5) for label in labels:

bw = BlockWindow(self, label=label) flag = flags.get(label, 0) sizer.Add(bw, 0, flag) self.SetSizer(sizer) self.Fit()

app = wx.PySimpleApp()

TestFrame().Show()

app.MainLoop()

In this example, widgets "one," "two," and "four" change which part of the grid they align with using the flags wx.ALlGN_BOTTOM, wx.ALlGN_CENTER, and wx.ALlGN_ right, respectively. You can see that as the window is resized, the widgets stay in contact with the side of their slot denoted by the flag (widget "three," which does not specify a flag, stays aligned to the top and left). Widgets "six" and "seven" both use the wx.EXPAND flag to tell the sizer to change their size to fill the available space, while widget "eight" uses wx.shaped to change its size while retaining a consistent proportion.

Table 11.2 shows the possible values of flag which are relevant for sizing and alignment.

Since these flags are a bitmask, they can be combined using |, in cases where that combination would be meaningful. So, wx.align_top | wx.align_right keeps the widget in the top right corner of its space. (Note that mutually exclusive values such as wx.align_top | wx.align_bottom will always resolve to the non-default

 Flag Description wx.ALIGN_BOTTOM Aligns the widget to the bottom of its allotted space. wx.ALIGN_CENTER Places the widget so that the center of the widget is in the center of its allotted space. wx.ALIGN_CENTER_HORIZONTAL Places the widget so that it is centered horizontally in its allotted space. wx.ALIGN_CENTER_VERTICAL Places the widget so that it is centered vertically in its allotted space. wx.ALIGN_LEFT Aligns the widget so that it is against the left edge of its allotted space. This is the default behavior. wx.ALIGN_TOP Aligns the widget so that it is against the top edge of its allotted space. This is the default behavior. wx.EXPAND Changes the size of the widget to fill its allotted space any time the size of the parent window changes. wx.FIXED_MINSIZE Causes the sizer to keep the minimum size of the item fixed, rather that checking if the item's best size has changed each time the sizer does a Layout(). wx.GROW The same as wx.expand but two whole characters shorter. Think of all the time you'll save! wx.SHAPED Changes the size of the widget such that it fills its allotted space along one dimension, and the other dimension is filled in proportion to the original shape of the widget. The proportional size of the smaller dimension cannot exceed the amount of space given to the widget by the sizer.

value. This is because the default values are integer 0 and would not change the value of the other operand in a bitwise or operation.)

There are a few methods that you can use to manipulate the size and positioning of a sizer or its component widgets at runtime. You can obtain the current size and position of the sizer itself using the methods GetSize() and GetPosition() â€” the position is relative to the container that the sizer is associated with. This is most helpful if the sizer is nested inside another sizer. You can force a sizer to take on a specific size by calling the method SetDimension(x, y, width, height). After this method is called, the sizer recalculates the size of its children based on its new size and position.