wxPython窗口布局

wxPython包含了许多强大的技术,用于控制你的窗口和控件的布局。它提供了几种可以替换的机制和几种有效的方法来完成同一件事情。允许程序员在特别的环境下使用可以工作最好或最习惯的机制。

约束

有一个叫做wxLayoutConstraints的类,它允许一个窗口位置和大小的说明是相对于它的“兄弟”(同级控件)和它的“父亲”(父控件)。每一个wxLayoutContraints对象是由八个wxIndividualLayoutConstraint对象组成,这些对象定义了不同类型的关系,就象哪一个窗口在这个窗口的上面,这个窗口的相对宽度是什么,等等。你通常需要指出八个中的四个约束条件,以便窗口被完全限定。例如,这个按钮将定位于它的父控件的中间,并且将总是占距父控件宽度的50%:

b = wxButton(self.panelA, 100, ‘ Panel A `)
lc = wxLayoutConstraints()
lc.centreX.SameAs (self.panelA, wxCentreX)
lc.centreY.SameAs (self.panelA, wxCentreY)
lc.height.AsIs ()
lc.width.PercentOf (self.panelA, wxWidth, 50)
b.SetConstraints(lc);

布局算法

名为wxLayoutAlgorithm的类实现了在MDI或SDI框架中子窗口的布局。它向框架的子控件发送 wxCalculateLayoutEvent事件,向它们查询它们的大小的信息。因为使用了事件系统,因此这个技术可以应用于任何窗口,甚至那些不需要知道布局的类。然而你可能希望将wxSashLayoutWindow类用在你的子窗口上,因为这个类提供了用于请求事件的处理器,和可以指定窗口大小的存取器。可以有选择地使用基类中的框格行为(sash behavior)使窗口可以由用户调整大小。wxLayoutAlgorithm被典型地应用在IDE风格的应用程序中,这种应用程序除了有MDI客户窗口或其它主要编辑窗口之外,还有几个可调整的窗口。可调整窗口可能包括了工具条,工具窗口,显示错误或警告消息的窗口。

大小管理器(sizer)

为了简化简单布局的编程,一个wxSizer类家族被加入到wxPython库中。这些类纯粹是用Python实现的,代替了从 wxWindows中封装C++代码。它们有点象是Java中布局管理的再现,你选择要用的sizer,然后向它增加窗口或其它sizer,这样它们将全部遵从布局的相同规则。例如,这个代码片段创建了五个按钮,它们在一个框子中水平排列,并且最后一个按钮允许伸缩以便填充框子中所分配的剩余的空间:

box = wxBoxSizer(wxHORIZONTAL)
box.Add(wxButton(win, 1010, "one"), 0)
box.Add(wxButton(win, 1010, "two"), 0)
box.Add(wxButton(win, 1010, "three"), 0)
box.Add(wxButton(win, 1010, "four"), 0)
box.Add(wxButton(win, 1010, "five"), 1)

资源

wxWindows库有一个可用的简单对话框编辑器,它可以帮助你安排一个对话框中控件的布局,并且生一个可在交叉平台上移植的资源文件。这个文件可以在运行时装入到程序中,并且可以立即转化成一个带有特别控件在上面的窗口。这个方法唯一的缺陷是你没有机会实现所生成窗口的子类化,但是如果用存在的控件类型和事件处理能够做你需要的任何事情,它应该执行的很好。最后,将会出现一个为wxPython特别设计的应用程序生成工具,它将为你或者生成资源文件或者生成实际的Python源代码。

强制力

最后,有一种强制力(brute force)机制,用来通过编程来指明每一个组件的精确位置。有时候一个窗口的布局需要不能适应任何一种sizer,或者不能保证约束的复杂性,或者布局算法。对于这些情况,你可以重新回到手工方式去处理,但是对于比Edit Transaction对话框复杂多的东西,你可能不想去尝试它。

wxDialog and friends

  下一步是建立一个用来编辑交易的对话框。对象由日期,说明,和不定数目的交易记录组成,每条记录都有一个帐户名和一个余额。我们知道,所有的记录加起来应该为0,并且日期应该为一个有效日期。另外,为了编辑日期和说明,你需要能够增加,编辑,和删除记录。图7显示了对于这个对话框的一个可能的布局,并且是这个例子中所使用的。

图7. wxPython Doubletalk交易编辑器

  因为这里有很多的代码,让我们一步步地仔细检查这个类的初始化过程。下面是第一部分:

class EditTransDlg(wxDialog):
def __init__(self, parent, trans, accountList):
wxDialog.__init__(self, parent, -1, "")
self.item = -1
if trans:
self.trans = copy.deepcopy(trans)
self.SetTitle("Edit Transaction")
else:
self.trans = Transaction()
self.trans.setDateString(dates.ddmmmyyyy(self.trans.date))
self.SetTitle("Add Transaction")

  这是想当简单的东西。只是调用了父类的__init__方法,做一些初始化工作,并且判断是否你正在编辑一个存在的交易或创建一个新的交易。如果正在编辑一个存在的交易,使用Python拷贝模块来生成对象的拷贝。这样做因为你可能正好在编辑交易,并不想让被编辑的交易的任何部分留在 BookSet中。如果对话框被用来增加一条新交易,则创建一条,然后修改它的日期,通过从日期中截去时间。在交易中的缺省日期包括了当前的时间,但是这个对话框只具备了处理日期部分。


评论

该日志第一篇评论

发表评论

评论也有版权!