Can I specify a minimum size for my sizer or its children

Another important factor in the layout of widgets within a sizer is the ability to specify a minimum size for the sizer itself or for any of its children. Often, you don't want a control or a sizer to get smaller than a particular size, usually because it will cause text to be cut off by the edge of the widget. Or, in the case of a nested sizer, an entire widget might no longer be displayed inside the window. Given their normal placement within a dialog, the OK and Cancel buttons are common candidates for falling off the edge of a frame this way. Few things are more frustrating for a user than having the buttons for dismissing a dialog disappear. Luckily, you can use the specified minimum size to prevent this from happening.

Figure 11.5 shows an example of setting the minimum size for a specific widget. This window has not been resized by a user.

Figure 11.5

A grid sizer with the size of one item set explicitly

Figure 11.5

A grid sizer with the size of one item set explicitly

Listing 11.4 shows the code to create this figure. It is similar to the basic grid code with the addition of a single call to SetMinSize().

Listing 11.4 A grid sizer with a minimum size set import wx from blockwindow import BlockWindow labels = "one two three four five six seven eight nine".split()

class TestFrame(wx.Frame):

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

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

bw = BlockWindow(self, label=label) sizer.Add(bw, 0, 0) center = self.FindWindowByName("five") center.SetMinSize((150,50)) self.SetSizer(sizer)

self.Fit() app = wx.PySimpleApp() TestFrame().ShowO app.MainLoop()

When a sizer is created, it implicitly creates a minimum size based on the combined minimum size of its children. Most controls know their minimum "best size," and the sizers query that value to determine the defaults of the layout. If the control is created with a size explicitly set, that size overrides the control's default calculation of its minimum best size. The minimum size of a control can also be set using the window methods SetMinSize(width, height) and SetSizeHints (minW, minH, maxW, maxH)—the latter method allowing you to specify a maximum size as well. A widget will usually adjust its best size if attributes of that widget— typically the display font or label text—change.

The best size of a container window is determined from its sizer if the window has one. If not, the window's best size is whatever is required to be large enough to show all its children at their current size. If the window has no children, its minimum size is used if set. If all else fails, the current size of the container window is used as its best size.

You can access the minimum size for the entire sizer with GetMinSize(). If you want to set a larger minimum size for the entire sizer, you do it using SetMinSize (width, height), which you can also invoke with a wx.Size instance—SetMin-Size(size), although in wxPython you'd rarely explicitly create a wx.Size. After the minimum size has been set, GetMinSize() returns either the explicit size or the combined size of the children, whichever is larger.

If you want only to set the minimum size of a specific child within the sizer, use the SetItemMinSize() method of the sizer. Like Detach(), there are three ways to invoke SetItemMinSize(), with a window, a sizer, or an index:

SetItemMinSize(window, size) SetItemMinSize(sizer, size) SetItemMinSize(index, size)

In this case, the window or sizer being set must be a child of the sizer instance being invoked. The method will search through the entire nested tree of sizers looking for the specific subwindow or subsizer if needed. The index is the index in the list of the sizer's children. The size parameter, either a wx.Size object or a (width, height) tuple, is the explicit minimum size of the item within the sizer. If the minimum size as you set it is greater than the current size of the widget, it is automatically resized. You can't set the maximum size from the sizer, only from the widget using SetSizeHints().

Was this article helpful?

0 0

Post a comment