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.

Wxpython Align Center Widgets

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

Table 11.2 Size and alignment behavior flags

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.

Was this article helpful?

0 0

Post a comment