Google

星期二, 七月 15, 2008

11.3.3 什么是box sizer?[wxPython in Action]

box sizer是wxPython所提供的sizer 中的最简单和最灵活的sizer。一个box sizer是一个垂直列或水平行,窗口部件在其中从左至右或从上到下布置在一条线上。虽然这听起来好像用处 太简单,但是来自相互之间嵌套sizer的能力使你能够在每行或每列很容易放置不同数量的项目。由于每个sizer都是一个独立的实体,因此你的布局就有 了更多的灵活性。对于大多数的应用程序,一个嵌套有水平sizer的垂直sizer将使你能够创建你所需要的布局。

图11.11-11.14 展示了几个简单的box sizer的例子。图中所展示的各个框架我们都是手动调整了大小的,以便展示每个sizer是如何响应框架的增大的。图 11.11显示了一个水平的box sizer,图11.12在一个垂直的box sizer显示了现图11.11相同的窗口部件。

图11.11


图11.12


图11.13显示了一个垂直的sizer,其中一个窗口部件被设置成可扩展并填充有效的垂直空间。图11.14展示了一个垂直的sizer,其中的两个窗口部件设置为按不同的比例占据有效的垂直空间。

图11.13


图11.14


生成以上四个sizer框架的示例代码如例11.9所示。

例11.9 产生多个box sizer

import wx
from blockwindow import BlockWindow

labels = "one two three four".split()

class TestFrame(wx.Frame):
title = "none"
def __init__(self):
wx.Frame.__init__(self, None, -1, self.title)
sizer = self.CreateSizerAndWindows()
self.SetSizer(sizer)
self.Fit()

class VBoxSizerFrame(TestFrame):
title = "Vertical BoxSizer"

def CreateSizerAndWindows(self):
sizer = wx.BoxSizer(wx.VERTICAL)
for label in labels:
bw = BlockWindow(self, label=label, size=(200,30))
sizer.Add(bw, flag=wx.EXPAND)
return sizer


class HBoxSizerFrame(TestFrame):
title = "Horizontal BoxSizer"

def CreateSizerAndWindows(self):
sizer = wx.BoxSizer(wx.HORIZONTAL)
for label in labels:
bw = BlockWindow(self, label=label, size=(75,30))
sizer.Add(bw, flag=wx.EXPAND)
return sizer

class VBoxSizerStretchableFrame(TestFrame):
title = "Stretchable BoxSizer"

def CreateSizerAndWindows(self):
sizer = wx.BoxSizer(wx.VERTICAL)
for label in labels:
bw = BlockWindow(self, label=label, size=(200,30))
sizer.Add(bw, flag=wx.EXPAND)

# Add an item that takes all the free space
bw = BlockWindow(self, label="gets all free space", size=(200,30))
sizer.Add(bw, 1, flag=wx.EXPAND)
return sizer

class VBoxSizerMultiProportionalFrame(TestFrame):
title = "Proportional BoxSizer"

def CreateSizerAndWindows(self):
sizer = wx.BoxSizer(wx.VERTICAL)
for label in labels:
bw = BlockWindow(self, label=label, size=(200,30))
sizer.Add(bw, flag=wx.EXPAND)

# Add an item that takes one share of the free space
bw = BlockWindow(self,
label="gets 1/3 of the free space",
size=(200,30))
sizer.Add(bw, 1, flag=wx.EXPAND)

# Add an item that takes 2 shares of the free space
bw = BlockWindow(self,
label="gets 2/3 of the free space",
size=(200,30))
sizer.Add(bw, 2, flag=wx.EXPAND)
return sizer

app = wx.PySimpleApp()
frameList = [VBoxSizerFrame, HBoxSizerFrame,
VBoxSizerStretchableFrame,
VBoxSizerMultiProportionalFrame]
for klass in frameList:
frame = klass()
frame.Show()
app.MainLoop()

box sizer是类wx.BoxSizer的实例,wx.BoxSizer是wx.Sizer的子类,相对于wx.Sizer,wx.BoxSizer几乎没有增加新的方法。wx.BoxSizer的构造函数有一个参数:

wx.BoxSizer(orient)

参 数orient代表该sizer的方向,它的取值可以是wx.VERTICAL或wx.HORIZONTAL。对于box sizer所定义的唯一一个新 的方法是GetOrientation(),它返回构造函数中orient的整数值。一旦一个box sizer被创建后,你就不能改变它的方向了。 box sizer的其它的函数使用本章早先所讨论的一般的sizer的方法。

box sizer的布局算法对待该sizer的主方向 (当构建的时候已被它的方向参数所定义)和次要方向是不同的。特别地,proportion参数只适用于当sizer沿主方向伸缩时,而 wx.EXPAND标记仅适用于当sizer的尺寸在次方向上变化时。换句话说,当一个垂直的box sizer被垂直地绘制时,传递给每个Add()方 法调用的参数proportion决定了每个项目将如何垂直地伸缩。除了影响sizer和它的项目的水平增长外,参数proportion以同样的方式影 响水平的box sizer。在另一方面,次方向的增长是由对项目所使用的wx.EXPAND标记来控制的,所以,在一个垂直的box sizer中的项 目将只在水平方向增长,如果它们设置了wx.EXPAND标记的话,否则这些项目保持它们的最小或最合适的尺寸。图6.7演示了这个过程。

在box sizer 中,项目的比例增长类似于flex grid sizer,但有一些例外。第一,box sizer的比例行为是在窗口部件被添加到该sizer时,使用 proportion参数被确定的——你无需像flex grid sizer那样单独地指定它的增长性。第二,比例为0的行为是不同的。在 box sizer中,0比例意味着该窗口部件在主方向上不将根据它的最小或最合适尺寸被调整尺寸,但是如果wx.EXPAND标记被使用了的话,它仍可 以在次方向上增长。当box sizer在主方向上计算它的项目的布局时,它首先合计固定尺寸的项目所需要的空间,这些固定尺寸的项目,它们的比例为0。 余下的空间按项目的比例分配。

标签: , ,

wxWidgets的Sizer

当我们需要写自己的dialog的时候,需要布置好控件的位置,界面才美观.可是如果控件比较多的化,难道我们需要对每个都指定坐标么?还有一个重要的问 题是,这个过程不是"所见即所得"!(当然现在wxWidgets也有可视的界面编辑器了,这里不考虑这个).这个对于从VC/Delphi转过来的程序 员会比较不适应,因为IDE有集成界面编辑器,非常方便调整界面.对于写过AWT(java),GTK,QT的人来说,相信都用过类似layout的东 西.wxWidgets中wxSizer就是做这个的.
  我们先说说一些基本的概念.
  1.所有的sizers都是容器.并且是可嵌套的.
  2.item的最小尺寸
  一般的控件最小尺寸就是初试化的时候的默认值.有些控件是可以计算他们的尺寸的(例如Checkbox),但是有些不好计算,例如listbox,宽高都是不确定的,因为可以有滚动条:-).有些则能计算高度,不能计算宽度,比如text control.
  3.item的边框
  包围着控件的周围的空白空间.每个控件都有自己的边框.边框的大小是可以设置的.位置也可以设置的,比如只有左边有边框,或者上下有,左右没有.
  4.item是可对齐的
   可以居中/上/小/左/右等对齐方式.
  5.item是可伸缩的
  一个item一般占用空间包括item的最小尺寸和边框.但是这个是可以伸缩的.
  6.item是可以手工设置为隐藏的
   使用wxSizer::Show函数实现.注意后面接着要调用Layout函数强制更新界面布局.当我们想隐藏部分界面的时候,这个功能非常有用.避免 我们做这样的事情:先从sizer中把控件移除,然后需要的时候在加入.但是要注意的,这个只有wxBoxSizer和wxFlexGridSizer支 持.
  我们在来看看wxWidgets都提供我们哪些类来完成控件的布局任务.
  wxSizer, wxGridSizer, wxFlexGridSizer, wxBoxSizer, wxStaticBoxSizer
  wxSizer是基类,一般我们都不直接使用.
  wxBoxSizer:
  可以指定是水平还是垂直方向排列item.只能二者选一.如果需要横竖混排,就需要嵌套使用.
  wxStaticBoxSizer:
   和wxBoxSizer一模一样,就是多了一个static box做为边框.
  wxGridSizer:
  就是表格状的排布.注意的是,所有的格子的大小都是一样的.具体的尺寸依赖item中最大的一个.
  wxFlexGridSizer:
  wxGridSizer的升级版本,每行的高度和每列的宽度是独立的.具体的大小依赖行/列中最大个高/宽.
  下面通过对wxBoxSizer的Add函数分析来详细说明wxBoxSizer使用方法.
  原形如下:
  wxSizerItem* Add(wxWindow* window, int proportion = 0,int flag = 0, int
  border = 0, wxObject* userData = NULL)
  wxSizerItem* Add(wxSizer* sizer, int proportion = 0, int flag = 0, int
  border = 0, wxObject* userData = NULL)
  一个是针对wxWindow的,一个是嵌套wxSizer用的,其他的参数都是一致的.
  参数说明:
  proportion:
  这个参数是用在wxBoxSizer的.前面说到每个wxBoxSizer是可以指定一个方向的,这个可以认为是wxBoxSizer的主方向.
  如果该参数是1,表示可以在主方向上伸缩需要加入的item.
  flag:
  指定item边框的位置(可以用"|"操作符号组合上/下/左/右).
  指定item对齐方式(可以用"|"操作符号组合上/下/左/右/垂直居中/水平居中).
   还有一个特别的wxEXPAND.指出item在非主方向是否可以伸缩,主方向的伸缩是由proportion指定.这里还有一个特别说明的(对主方向 和非主方向都有效),如果父级的sizer限制了不能伸缩尺寸,子级的sizer是不能更改的,就算设置可以伸缩也是无效的.如果父级的能伸缩,子级的 sizer可以设置为不能伸缩.
  这里就不举具体的例子说明了.确实需要可以参考wxWidgets的帮助中的"Topic
  overviews"中的"Sizer overview"的"Programming with
  wxBoxSizer".本文也是参考"Sizer overview"写的.
http://blog.csdn.net/Utensil/archive/2007/12/19/1953355.aspx

标签: ,

星期五, 六月 20, 2008

wxpython:sizer学习

使用sizer后,mainFrame的大小由sizer的孩子决定

grid sizer:

最简单的一个种sizer,各个栅的大小相同,栅的最大大小取决以栅中最大孩子的尺寸(当一个sizer被创建时,它根据它的孩子的综合的最小尺寸(最小的宽度和最小的高度)隐含地创建一个最小尺寸。),如果一个栅没有孩子,不会占有效空间的.gridsizer不会限制孩子的个数的,即使在开始声明也是一样

=========================

flex grid sizer

默认情况下,当尺寸调整时,它不改变它的单元格的尺寸。

可以指定某方向上的行为(以行或列为其它单位,gridsizer是以整体为单位),每个栅的宽度是该列中宽度最大的项目的宽度,它们的高度是该行中宽度最高的项目的宽度。显式地告诉该sizer该行或列是可扩展的:

当窗体大小变化时,需要显式地告诉该sizer该行或列是可扩展的:
AddGrowableCol(idx, proportion=0)
AddGrowableRow(idx, proportion=0)

SetFlexibleDirection(direction)

SetNonFlexibleGrowMode(mode)

=========================
grid bag sizer

1、能够将一个窗口部件添加到一个特定的单元格。(如果一个栅没有孩子,会占有效空间的)
2、能够使一个窗口部件跨越几个单元格(就像HTML表单中的表格所能做的一样)。

注意这里的Add()方法与以前的看起来有点不同 :

1 Add(window, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)

2 Add(sizer, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)

3 Add(size, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)

4 AddItem(item)
比其它sizer多了一个位置参数:因为它为孩子预留了空间

============== 下面是通用方法 ================

sizer对象的构造方法有两个比较重要的参数:

flag:窗体风格,对齐方式,边框位置

proportion:如果使用窗体大小变化时的空间使用,为一个比例值

孩子指定一个最小的尺寸

窗口的方法

SetMinSize(width, height)

SetSizeHints(minW, minH, maxW, maxH)

使用sizer的SetItemMinSize()方法。它也有三个形式:

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

对sizer添加或移除孩子:

Add(window, proportion=0, flag=0, border=0, userData=None)
Add(sizer, proportion=0, flag=0, border=0, userData=None)
Add(size, proportion=0, flag=0, border=0, userData=None)

Insert(index, window, proportion=0, flag=0, border=0, userData=None)
Insert(index, sizer, proportion=0, flag=0, border=0, userData=None)
Insert(index, size, proportion=0, flag=0, border=0, userData=None)

Prepend(window, proportion=0, flag=0, border=0, userData=None)
Prepend(sizer, proportion=0, flag=0, border=0, userData=None)
Prepend(size, proportion=0, flag=0, border=0, userData=None)

Detach(window)
Detach(sizer)
Detach(index)

管理它的孩子的尺寸和对齐的

调整grid sizer的大小时,每个部件之间的间隙将随之改变,但是默认情况下,窗口部件的尺寸不会变,并且始终按左上角依次排列

添加一个窗口部件到sizer时,可以通过给flag参数一个特定值来调整该窗口部件的尺寸改变行为。
wx.ALIGN_BOTTOM:按照窗口部件被分配的空间(格子)的底部对齐。

wx.ALIGN_CENTER:放置窗口部件,使窗口部件的中心处于其所分配的空间的中心。

wx.ALIGN_CENTER_HORIZONTAL:在它所处的格子中,水平居中。

wx.ALIGN_CENTER_VERTICAL :在它所处的格子中,垂直居中。

wx.ALIGN_LEFT:靠着它所处的格子左边缘。这是默认行为。

wx.ALIGN_TOP:靠着它所处的格子的上边缘。这是默认的行为。

wx.EXPAND:填满它所处的格子空间。

wx.FIXED_MINSIZE:保持固定项的最小尺寸。

wx.GROW:与wx.EXPAND相同。但比之少两个字符,节约了时间。

wx.SHAPED:窗口部件的尺寸改变时,只在一个方向上填满格子,另一个方向上按窗口部件原先的形状尺寸的比列填充。什么方向的sizer就向什么方向增长

管理每个孩子的边框

边框是连续数量的空白空间,方向有:wx.BOTTOM, wx.LEFT, wx.RIGHT, wx.TOP

传递了边框信息到flags参数后,也需要传递边框宽度的像素值给border参数 ,为边框的大小

http://sellroad.w58.ws86.com/jessinio/?p=512

标签: , , ,

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger