7.2 窗口布局控件

wxWidgets使用的窗口布局控件的算法和其它GUI程序开发框架的算法,例如Java的AWT,GTK+以及Qt等是非常相似的.它们都是基于这样的一个假设,那就是每一个窗口可以报告它们自己需要的最小尺寸以及当它们父窗口的大小发生改变的时候它们的可伸缩能力.通常这也意味着程序代码中没有给对话框中的控件设定固定的大小,取而代之的是设置了一个窗口布局控件,这个窗口布局控件会被寻问它最需要的合适大小,而窗口布局控件则会一次询问它内部的那些窗口,空白区域,控件以及其它的窗口布局控件最合适的大小,以此类推.要注意布局控件并非是wxWindow的派生类,因此不具有TAB顺序,所需要的系统开销也比一个真实的窗口要小的多.布局控件建立的是一种包含继承关系,在一个复杂的对话框里,这种包含继承关系的层级可能会很深,但是所有这些布局控件中的窗口或控件在窗口继承关系中可能都是兄弟控件,它们都以这个对话框作为自己的父窗口.

在对话框编辑软件中,布局控件的包含继承关系以一种更直观的图形化方式表示.下图演示了Anthemion软件公司的 DialogBlocks软件编辑一个个人对话框时候的样子,这个对话框我们会在第9章,"创建自己的对话框"中作为一个例子.一个红色的方框围绕在当前选择的控件上,而蓝色的方框则用来指示其直接父容器的范围,左边显示的是对话框的容器继承关系树,当然所有这些控件还是有它们自己的窗口继承关系的,正如我们前面提到的那样,窗口继承关系树和容器继承关系树有很大的区别.

为了更清楚的说明容器继承关系和窗口继承关系的不同,我们用下图来大概的表示上图中的容器继承关系.下图中,阴影部分代表实际的窗口,而白色区域则代表布局控件.可以看出,对话框首先使用了两个垂直布局控件,以便在对话框周围释放出一个合理的边界区域,里面的那个垂直布局控件中有两个水平布局控件和一些其它的控件,其中一个水平布局控件中还定义了一截空白区域以便使得其中一个控件远离同组中另外的控件.正象你看到的那样,使用布局控件就象使用一堆大小不等的硬纸片进行摆放,然后把各个窗口控件放置到硬纸片的合适的位置.当然这个比喻并不完全贴切因为,硬纸片的大小是不会伸缩的.

目前为止wxWidgets总共支持五类布局控件,每一中布局控件或者用来实现一种特殊的布局方式,或者用来实现和布局相关的一种特殊的功能比如在某些控件周围围绕一个静态的文本框.接下来的小节我们会对它们进行一一的介绍.

布局控件的通用特性

所有的布局控件都是容器,这就是说,它们都是用来容纳一个或多个别的窗口或者元素的,不论每个单独的布局控件怎样排放它们的子元素,所有的子元素都必然有下面这些通用的特性.

最小大小: 布局控件中的每个元素都有计算自己的最小大小的能力(这往往是通过每个元素的DoGetBestSize函数计算出来的).这是这个元素的自然大小.举例来说,一个复选框的自然大小等于其复选框图形的大小加上其标签的最合适大小.当然,你可以给某个控件在其构造函数中指定固定的大小,并且在把它增加到布局控件中时指定wxFIXED_MINSIZE以改变自动计算的最小大小.需要注意的是,不是每个控件都可以计算自己的大小,对于类似列表框这样的控件来说,你必须清晰的指明它的大小,因为它们没有自然大小.另外一些控件则只拥有自然高度不拥有自然宽度,比如一个单行的文本框.下图演示了当对话框中只有一个控件的时候,以上三种控件怎样扩展对话框以适合自己的最小大小.

边界: 每个元素都应该有一个边界.所谓边界指的是用来和别的元素分开的空白区域,边界的最小大小必须被显式的指定,一般设置为5个象素.下图演示了对话框只有一个按钮控件但是指定了0,5和10作为最小边界值的时候的样子.

对齐方式: 每个元素都可以被以居中或者对齐某个边的方式放置.下图演示了一个水平的布局控件,在其中增加了一个列表框,一个和三个按钮,其中第一个按钮以居中方式增加,第二个则为上对齐,第三个则为下对齐方式.对齐既可以是水平方向的也可以是垂直方向的,但是对于大多数布局控件来说,只有一个方向是有效的.比如对于水平布局控件来说,只有垂直方向是有效的,因为水平方向的空间是被所有的子元素分割的,因此设置水平对齐方式是没有意义的(当然,为了达到水平对齐的效果,我们可能需要插入一个水平方向的空白区域,关于这点我们不作太多的说明).

伸缩因子: 如果一个布局控件的空间大于它所有子元素所需要的空间,那么我们需要一个机制来分割多余的空间.为了实现这个目的,布局控件中的每一个元素都可以指定一个伸缩因子,如果这个因子设置为默认值0,那么子元素将保持其原本的大小,大于0的值用来指定这个子元素可以分割的多余空间的比例,因此如果两个子元素的伸缩因子为1,其它子元素的伸缩机制为0,那么这两个子元素将会各占用多余空间的50%的大小,下图演示了一个对话框有三个按钮它们的初始大小和其中一个的伸缩因子设为1以后各自的大小.

注意在wxWidgets的手册中,有时不使用伸缩因子(stretch factor)这个词,而用比例(proportion)这个词表示相同的含义.