目录
Sizers背后的理念
共同特征
最小大小
边框
对齐方式
伸缩因子
使用 Sizer 隐藏控件
wxBoxSizer
wxStaticBoxSizer
wxGridSizer
wxFlexGridSizer
布局器(Sizers),由wxWidgets类层次结构中的wxSizer
类及其派生类表示,已成为wxWidgets中定义对话框控件布局的首选方法。这是因为它们能够创建视觉上吸引人的对话框,而不受平台限制,同时考虑到各个控件的大小和样式差异。
本文将描述和展示使用sizers可以做什么。随后的部分将简要介绍如何使用单独的sizer类进行编程。
关于能够描述基于sizer的对话框的wxWidgets资源系统的信息,请参阅基于XML的资源系统(XRC)。
另请参阅:wxSizer
, wxBoxSizer
, wxStaticBoxSizer
, wxStdDialogButtonSizer
, wxWrapSizer
, wxGridSizer
, wxFlexGridSizer
, wxGridBagSizer
Sizers背后的理念
wxWidgets中Sizers使用的布局算法与其他GUI工具包(如Java的AWT、GTK工具包或Qt工具包)中的布局系统密切相关。它基于单个子窗口报告其所需的最小大小以及如果父窗口大小发生变化时它们能够伸展的能力。这通常意味着程序员不需要设置对话框的初始大小,而是将sizer分配给对话框,并查询这个sizer以获得推荐的大小。反过来,这个sizer将查询其子元素(可以是普通的窗口、空白空间或其他sizer),以便构建sizer的层次结构。请注意,wxSizer
不是从wxWindow
派生的,因此不会干扰标签顺序,与屏幕上的真实窗口相比,它所需的资源非常少。
使得sizer在wxWidgets中如此适合使用的事实是,每个控件都报告自己的最小大小,并且该算法可以毫无问题地处理不同平台上字体大小或不同窗口(对话框项)大小之间的差异。例如,如果Linux/GTK小部件的标准字体和整体设计需要比Windows更多的空间,那么在Linux/GTK上的初始对话框大小将自动比Windows上的大。
目前,wxWidgets中有七种不同类型的sizer可用。每一种都代表了在对话框中以某种方式布局对话框项,或者完成特殊任务,如将一个静态框包装在对话框项(或另一个sizer)周围。这些sizer将在下面的文本中逐一讨论。有关如何使用sizer进行编程的更多详细信息,请参阅wxBoxSizer部分。
共同特征
所有sizer都是容器,即它们用于布局一个对话框项(或几个对话框项),这些项包含在sizer中。这些项有时被称为sizer的子项。无论各个sizer如何布局其子项,所有子项都有某些共同的特征:
最小大小
这个最小大小通常与控件的初始大小相同,可以在控件构造函数的wxSize字段中明确设置,或者由wxWidgets计算得出,通常是通过将项目的高度和/或宽度设置为-1。请注意,只有一些控件可以计算其大小(如复选框),而其他控件(如列表框)没有自然的宽度或高度,因此需要明确指定大小。有些控件可以计算其高度,但不能计算其宽度(例如单行文本控件):
边框
边框只是空白空间,用于在对话框中分隔对话框项。这个边框可以是全方位的,也可以是任何组合的一侧,例如仅位于控件的上方和下方。这个边框的厚度必须明确设置,通常是5个点。以下示例展示了只有一个对话框项(一个按钮)以及围绕按钮的0、5和10像素的边框:
对齐方式
通常,对话框项会被分配比其最小大小加上边框更多的空间。根据用于相应对话框项的标志,对话框项可以填充所有可用空间,即它会增长到比最小大小更大的尺寸,或者它会移动到可用空间的中心或空间的任一侧。以下示例展示了水平盒子sizer中的一个列表框和三个按钮;一个按钮居中对齐,一个顶部对齐,一个底部对齐:
伸缩因子
如果sizer包含多个子项,并且被提供的空间多于其子项和它们的边框所需的空间,就会出现如何在子项之间分配剩余空间的问题。为此,可以为每个子项分配一个伸缩因子,其中默认值为0表示子项不会获得比其请求的最小大小更多的空间。大于零的值是根据相应sizer子项中所有伸缩因子的总和来解释的,即如果两个子项都获得伸缩因子1,它们将各自获得一半的额外空间,无论一个控件的最小尺寸是否比另一个差。以下示例展示了一个包含三个按钮的对话框,第一个按钮的伸缩因子为1,因此会拉伸,而其他两个按钮的伸缩因子为0,保持其初始宽度:
使用 Sizer 隐藏控件
你可以使用 wxWindow::Show()
方法来隐藏 sizer 中的控件,就像隐藏任何其他控件一样。然而,wxSizer
也提供了一个独立的方法,可以告诉 sizer 在其大小计算中不考虑该控件。要使用 sizer 隐藏窗口,请调用 wxSizer::Show()
。然后,你必须调用 sizer 上的 Layout
方法来强制更新。
这在隐藏界面部分时很有用,因为你可以避免从 sizer 中移除控件并稍后重新添加它们。
注意:这仅由 wxBoxSizer
和 wxFlexGridSizer
支持。
wxBoxSizer
wxBoxSizer
可以根据其构造函数中使用的标志将其子项垂直或水平排列。当使用垂直 sizer 时,每个子项可以居中对齐、右对齐或左对齐。相应地,当使用水平 sizer 时,每个子项可以居中对齐、底部对齐或顶部对齐。上一节中描述的伸缩因子用于主要方向,即当使用水平 box sizer 时,伸缩因子决定了子项可以水平拉伸多少。以下示例展示了与上一个示例相同的对话框,但 box sizer 现在是一个垂直 box sizer:
wxStaticBoxSizer
wxStaticBoxSizer
与 wxBoxSizer
相同,但周围有一个静态框。以下是一个示例:
wxGridSizer
wxGridSizer
是一个二维 sizer。所有子项都被赋予相同的大小,这是由最大的子项所需的最小大小决定的,在这种情况下是左下角边框中的文本控件。列数或行数中的任何一个是固定的,如果添加了新的子项,网格 sizer 将在相应的另一个方向上增长:
wxFlexGridSizer
wxFlexGridSizer
是从 wxGridSizer
派生出的二维 sizer。每列的宽度和每行的高度都是根据各自最大子项的最小要求单独计算的。此外,如果 sizer 被分配了一个与其请求的大小不同的尺寸,可以声明列和行是可伸缩的。以下示例显示了与上面相同的对话框,但使用了 flex 网格 sizer:
--- END ---