11.3 使用其它类型的sizer [wxPython in Action]

11.3 使用其它类型的sizer

我们已经讨论了基本的sizer,现在我们可以转向更复杂和更灵 活的sizer了。其中两个(flex grid sizer和grid bag sizer)本质上是grid的变种。另外两个(box和 static box sizer)使用一个不同的和更灵活的布局结构。

11.3.1 什么是flex grid sizer?

flex grid sizer是grid sizer的一个更灵活的版本。它与标准的grid sizer几乎相同,除了下面的例外:

1、每行和每列可以有各自的尺寸。
2、默认情况下,当尺寸调整时,它不改变它的单元格的尺寸。如果需要的话,你可以指定哪行或哪列应该增长。
3、它可以在两个方向之一灵活地增长,意思是你可以为个别的子元素指定比列量,并且你可以指定固定方向上的行为。

图11.7显示了一个flex grid sizer,它的布局也是9个单元格。这里的中间单元格更大。

图11.7


与 图11.5相比较,对于相同的布局,图11.5中每个单元格的尺寸与中间对象的相同,在flex grid sizer中,单元格的尺寸大小根据它所在的 行和列来定。它们宽度是该列中宽度最大的项目的宽度,它们的高度是该行中宽度最高的项目的宽度。在这里,项目“four”和项目“six”的单元格的高度 比项目本身的高度更高,因为其同行中的项目“five”,而"two"和"seven"的单元格的宽度也更宽。“one,” “three,” “seven,” 和“nine”的单元格是正常的尺寸,并且不受较大的窗口部件的影响。

图11.8展示了当调整窗口尺寸时,flex grid sizer的默认行为——单元格的尺寸不改变。

图11.8


例11.6显示了产生了图11.8的代码

例11.6 创建一个flex grid sizer

import wx
from blockwindow import BlockWindow

labels = "one two three four five six seven eight nine".split()

class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "FlexGridSizer")
sizer = wx.FlexGridSizer(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().Show()
app.MainLoop()

一个flex grid sizer是wx.FlexGridSizer的一个实例。类wx.FlexGridSizer是wx.GridSizer的子类,所以wx.GridSizer的属性方法依然有效。wx.FlexGridSizer的构造函数与其父类的相同:

wx.FlexGridSizer(rows, cols, vgap, hgap)

为了当sizer扩展时,使一行或列也扩展,你需要使用适当的方法显式地告诉该sizer该行或列是可扩展的:

AddGrowableCol(idx, proportion=0)
AddGrowableRow(idx, proportion=0)

当sizer 水平扩展时,关于新宽度的默认行为被等同地分配给每个可扩展的列。同样,一个垂直的尺寸调整也被等同地分配给每个可扩展的行。要改变这个默认的行为并且使 不同的行和列有不现的扩展比率,你需要使用proportion参数。如果proportion参数被使用了,那么与该参数相关的新的空间就被分配给了相 应的行或列。例如,如果你有两个尺寸可调整的行,并且它们的proportion分别是2和1,那么这第一个行将得到新空间的2/3,第二行将得到 1/3。图11.9显示使用proportional(比列)空间的flex grid sizer。在这里,中间行和列所占的比例是2和5,两端的行和 列所占的比例是1。

图11.9


正如你可以看到的,当所有的单元格增大时,中间的行和列的增大是两端的两倍。窗口部件的没有改变尺寸以填表充它们的单元格,虽然可以通过在当它们被添加到sizer时使用wx.EXPAND来实现。例11.7显示了产生图11.9的代码。

例11.7

import wx
from blockwindow import BlockWindow

labels = "one two three four five six seven eight nine".split()

class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Resizing Flex Grid Sizer")
sizer = wx.FlexGridSizer(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))
sizer.AddGrowableCol(0, 1)
sizer.AddGrowableCol(1, 2)
sizer.AddGrowableCol(2, 1)
sizer.AddGrowableRow(0, 1)
sizer.AddGrowableRow(1, 5)
sizer.AddGrowableRow(2, 1)
self.SetSizer(sizer)
self.Fit()

app = wx.PySimpleApp()
TestFrame().Show()
app.MainLoop()

如果你对一个可扩展的行或列使用了比例尺寸,那么你需要对该方向上的所有可扩展的行或列指定一个比例量,否则你将得到一个糟糕的效果。

在flex grid sizer 中还有另外一个机制用于控制窗口部件的增长(执不执行先前AddGrowable*方法的设置)。默认情况下,比例尺寸适用于flex grid的两个方 向;但是你可以通过使用SetFlexibleDirection(direction)方法来指定仅某个方向应该按比例调整尺寸,参数 direction的值可以是:wx.HORIZONTAL, wx.VERTICAL, 或wx.BOTH (默认值)。然后你可以使用 SetNonFlexibleGrowMode(mode)方法来指定另一个方向上的行为。例如,如果你调用了SetFlexibleDirection (wx.HORIZONTAL)方法,列的行为就遵循AddGrowableCol(),然后调用SetNonFlexibleGrowMode()来定 义行的行为。表11.3显示了mode参数的有效值。

表11.3

wx.FLEX_GROWMODE_ALL:flex grid在没有使用SetFlexibleDirection*的方向上等同地调整所有单元格的尺寸。这将覆盖使用AddGrowable*方法设置的任何行为——所有的单元格都将被调整尺寸,不管它们的比例或它们是否被指定为可扩展(增长)的。

wx.FLEX_GROWMODE_NONE:在没有使用SetFlexibleDirection*的方向上的单元格的尺寸不变化,不管它们是否被指定为可增长的。

wx.FLEX_GROWMODE_SPECIFIED:在没有使用SetFlexibleDirection*的方向上,只有那些可增长的单元格才增长。但是sizer将忽略任何的比例信息并等同地增长那些单元格。这是一个默认行为。

上 面段落中所讨论的SetFlexibleDirection和SetNonFlexibleGrowMode方法都有对应的方法: GetFlexibleDirection()和GetNonFlexibleGrowMode(),它们返回整型标记。在上表中要强调的是,任何使用这 些方法来指定的设置将取代通过AddGrowableCol()和AddGrowableRow()创建的设置。
posted @ 2008-01-31 15:38  Yoshow  阅读(1079)  评论(0)    收藏  举报