接口 WTable 部件类似于标准的 gtk.Table。它是从 gtk.Container 派生而来的。其主要的不同点在于:
- 不需要预先确定行和列的数量。
- gtk.Table 的 attach 方法提供了可选的 xoptions=GTK.EXPAND|GTK.FILL, yoptions=GTK.EXPAND|GTK.FILL, xpadding=0, ypadding=0 参数,而 WTable.attach 方法有一个可选的 glue 参数,后面会谈到这个参数。
清单 1. WTable 构造函数1
2
3
4
5
6
| class WTable(GTK.Container):
def __init__(self, maxsize=None):
GTK.Container.__init__(self)
self.gChildren = []
self.maxsize = maxsize or (gdk.screen_width(), gdk.screen_height())
|
默认情况下,清单 1 中的 self.maxsize 实际上对 WTable 的宽度和高度没有约束。
attach 方法有以下接口:
清单 2. WTable.attach 接口1
| def attach(self, widget, leftright=(0,1), topbottom=(0,1), glue=None):
|
leftright 和 topbottom 是分别用于列和行的类 STL(标准模板库)的半开区间(half-open range)。区间 [a,b) 或 (a,b] 是半开的,其一端是 “打开的”(不包括它的极限点),另一端是 “关闭的”(包括它的极限点)。对于 glue 参数,要注意我如何使用 (0,1) 索引。
维和枚举 水平维与垂直维是对称的。这里不使用乘法代码(multiplying code),而是使用以下维枚举: (X, Y) = (0, 1)。我们在循环中使用它,索引大小为 2 的数组。对于左、右、上、下边距以及它们相关的 Spring 类,我们也使用类似的 (0,1) 枚举(后面有更详细的描述)。
注意,gtk.Requisition(该对象包含有关部件所需空间需求的信息)具有 width 和 height 字段,其空间分配由 gtk.gdk.Rectangle(包含关于一个矩形的数据的对象)指定,gtk.gdk.Rectangle 具有 x、y、 width 和 height 字段,这些字段没有使用方便的索引。
用 Glue 实现附加 当 WTable 附加了一个部件时,会创建一个 child 对象,并将该对象添加到 WTable 的 gChildren 列表中。child 有以下类定义:
清单 3. Child1
2
3
4
5
6
7
| class Child:
"Child of WTable. Adoption data"
def __init__(self, w, leftright=(0,1), topbottom=(0,1), glue=None):
self.widget = w
# lrtb: 2x2 tuple Cols[begin, end), Rows[Begin, end) )
self.lrtb = (leftright, topbottom)
self.glue = glue
|
它存放传递给 WTable attach 方法的数据。
Glue 类同时处理两个维。它由两个单维的 Glue1D 方法组成:
清单 4. Glue1
2
3
4
| class Glue:
"2-Dimensional Glue"
def __init__(self, xglue=None, yglue=None):
self.xy = (xglue or Glue1D(), yglue or Glue1D())
|
每个 Glue1D 由一个 grow weight 值和两个 spring 组成,取决于不同的维,这两个 spring 可以是 left 和 right 或 top 和 bottom。我们将这些类型的值称作 wGrow。
清单 5. Glue1D1
2
3
4
5
| class Glue1D:
"1-Dimensional Glue"
def __init__(self, preSpring=None, postSpring=None, wGrow=1):
self.springs = (preSpring or Spring(), postSpring or Spring())
self.wGrow = wGrow # of owning widget
|
最后,Spring 类由下面的类构造函数中显示的值组成。
清单 6. Spring1
2
3
4
5
| class Spring:
"One side attachment requirement"
def __init__(self, pad=0, wGrow=0):
self.pad = pad
self.wGrow = wGrow
|
总之,一个 Glue 对象包含 4 个 Spring 对象,这 4 个 Spring 影响边距的大小。(2x(1+2)=6) wGrow 值扮演两个 角色:
- 全局性确定行或列获得的相关的额外像素空间。
- 对于每个附加的 child,局部确定 child 与它的(2x2=4)边距之间的额外空间的分配。
为方便起见,我们使用以下的 “total wGrow” 方法:
清单 7. Glue1D.total_grow_weight1
2
| def total_grow_weight(self):
return self.wGrow + self.springs[0].wGrow + self.springs[1].wGrow
|
然后,返回来看看 attach 方法。(注意,您实际上是允许方便地指定单个的列和单个的行,而不是一个列和行区间。
清单 8. WTable.attach1
2
3
4
5
6
7
8
9
10
11
12
13
| def attach(self, widget, leftright=(0,1), topbottom=(0,1), glue=None):
if glue == None:
glue = Glue()
# Conveniently change possible single n value to (n,n+1)
lrtb = map(lambda x: (type(x) == types.IntType) and (x, x+1) or x,
(leftright, topbottom))
child = Child(widget, lrtb[0], lrtb[1], glue)
self.gChildren.append(child)
if self.flags() & GTK.REALIZED:
widget.set_parent_window(self.window)
widget.set_parent(self)
self.queue_resize()
return child
|
|