使用容器

锚点是处理 GUI 中基本多分辨率处理的不同纵横比的有效方法,

对于更复杂的用户界面, 它们可能会变得难以使用.

这通常是游戏的情况下, 如角色扮演类, 在线聊天, 大富翁类或模拟类游戏. 另一个需要更高级布局功能的常见情况是游戏内工具(或者仅仅是工具).

这些情况需要一个更强大的类似操作系统的用户界面,具有先进的布局和格式。用 Container 会更方便。

容器布局

容器提供了巨大的布局能力(例如,Godot编辑器的用户界面就是完全使用它们完成的):

../../_images/godot_containers.png

当使用 Container 派生的节点时,所有作为子项的 Control 节点都会放弃自我定位能力。这意味着容器将控制它们的位置,任何手动更改这些节点的尝试,都将在它们的父节点下一次调整大小时被忽略或失效。

同样,调整 Container 派生节点的大小时,它的所有子节点都将根据它重新定位,其行为基于所用的容器类型:

../../_images/container_example.gif

HBoxContainer 调整子按钮大小的例子。

容器的真正优势在于它们可以嵌套(作为节点), 允许创建非常复杂的布局, 调整毫不费力.

大小标志

当向容器添加节点时, 容器对待每个子元素的方式, 主要取决于它们的 size flags尺寸标记 . 通过检查 容器 的子控件, 可以找到这些标记.

../../_images/container_size_flags.png

尺寸标记独立于垂直和水平尺寸, 并不是所有容器都使用它们(但大多数容器都使用):

  • Fill填充 : 确保控件 fills填充 容器内指定的区域. 无论控件是否 expands扩展 (见下面), 当此选项被选中时(默认情况), 只 填充 指定区域.

  • Expand扩展 : 试图在父容器中尽可能多地使用空间(在每个轴中). 不展开的控件会被展开的控件推开. 在扩展的控件之间, 它们相互占用的空间大小由 Ratio 决定(见下文).

  • Shrink Center收缩中心 当扩展时(如果不填充), 尽量保持在扩展区域的中心(默认情况下, 它仍然位于左侧或顶部).

  • Ratio比例 扩展控件之间, 相互占用可用空间的简单比例. 一个比例为 “2” 的控件, 将占用比例为 “1” 控件的两倍可用空间.

建议使用这些标记和不同的容器进行试验, 以便更好地了解它们是如何工作的.

容器类型

Godot提供了几种开箱即用的容器类型, 因为它们有不同的用途:

盒式容器

将子控件垂直或者水平排列(使用 HBoxContainerVBoxContainer )。而在相对方向上(比如水平容器的垂直方向),子节点会被扩展。

../../_images/containers_box.png

这些容器会用到设置了 Expand(扩展) 选项的子节点的 Ratio(比例) 属性。

网格容器

将子控件按照网格排列(使用 GridContainer ,必须指定列数),会同时用到垂直和水平扩展选项。

../../_images/containers_grid.png

边距容器

将子节点扩展到该控件的边界(使用 MarginContainer ),会根据主题的设置来添加不同大小的边距。

../../_images/containers_margin.png

同样, 请记住, 边距是一个 Theme 值, 所以它们需要从每个控件的常量重写部分进行编辑:

../../_images/containers_margin_constants.png

选项卡容器

允许你将多个子控件堆叠在一起(使用 TabContainer ),只会显示 当前 控件。

../../_images/containers_tab.png

点击容器顶部的选项卡可以更改 当前 控件:

../../_images/containers_tab_click.gif

标题默认是根据节点名称生成的(尽管可以通过 TabContainer 的 API 重写)。

可以在 TabContainer 的主题覆盖项中修改类似选项卡位置和 StyleBox 等设置。

拆分容器

只接受单个或者两个子控件,会将它们相邻放置,中间是分隔线(使用 HSplitContainerVSplitContainer ),会使用到水平和垂直选项以及 Ratio 属性。

../../_images/containers_split.png

可以通过拖动分隔线来调整两个子节点所占区域的大小:

../../_images/containers_split_drag.gif

PanelContainer

绘制 StyleBox 的简单容器,会将子节点扩大到整个区域(使用 PanelContainer,会考虑 StyleBox 的边距)。它同时考虑水平和垂直尺寸标志。

../../_images/containers_panel.png

这个容器作为顶层非常有用, 或者只是为布局各个部分添加自定义背景.

ScrollContainer

接受一个单独的子节点. 如果这个节点比容器大, 将添加滚动条以允许移动节点(通过 ScrollContainer)。垂直和水平尺寸标志都会被遵守,该行为可以在属性中的每个轴上打开或关闭.

../../_images/containers_scroll.png

鼠标滚轮和触摸拖动(当触摸可用时)也是平移子控件的有效方法.

../../_images/containers_center_pan.gif

正如上面的例子中所展示的,使用此容器最常见的方法之一,是将 VBoxContainer 作为子容器一起使用。

ViewportContainer

这是一个特殊的控件,只接受单个 Viewport 节点作为子节点,并且会把它作为图片显示(使用 ViewportContainer)。

创建自定义容器

可以使用脚本轻松地创建自定义容器。下面是一个简单容器的例子,它会根据自身的矩形尺寸调整子节点:

GDScript

  1. extends Container
  2. func _notification(what):
  3. if what == NOTIFICATION_SORT_CHILDREN:
  4. # Must re-sort the children
  5. for c in get_children():
  6. # Fit to own size
  7. fit_child_in_rect( c, Rect2( Vector2(), rect_size ) )
  8. func set_some_setting():
  9. # Some setting changed, ask for children re-sort
  10. queue_sort()