容器

:ref:`锚点<doc_size_and_anchors>`是处理图形用户界面中基本多分辨率处理的不同纵横比的有效方法,

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

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

这些情况需要一个更强大的类似操作系统的用户界面,具有先进的布局和格式。为此,:ref:`容器<class_container>`更有用。

Container layout

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

../../_images/godot_containers.png

当使用:ref:`容器<class_Container>`派生节点时,所有:ref:`控制<class_Control>`子节点放弃了自己的定位能力。这意味着*容器*将控制它们的位置,任何手动更改这些节点的尝试,都将在它们的父节点下一次调整大小时被忽略或失效。

Likewise, when a Container derived node is resized, all its children will be re-positioned according to it, with a behavior based on the type of container used:

../../_images/container_example.gif

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

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

大小标志

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

../../_images/container_size_flags.png

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

  • 填充:确保控件*填充*容器内指定的区域。无论控件是否*扩展*(见下面),当此选项被选中时(默认情况),只*填充*指定区域。
  • Expand: Attempts to use as much space as possible in the parent container (in each axis). Controls that don't expand will be pushed away by those that do. Between expanding controls, the amount of space they take from each other is determined by the Ratio (see below).
  • **收缩中心**当扩展时(如果不填充),尽量保持在扩展区域的中心(默认情况下,它仍然位于左侧或顶部)。
  • **比例**扩展控件之间,相互占用可用空间的简单比例。一个比例为“2”的控件,将占用比例为“1”控件的两倍可用空间。

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

Container types

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

Box Containers

垂直或水平排列子控件(通过:ref:水平盒子容器<class_HBoxContainer>`和:ref:`垂直盒子容器<class_VBoxContainer>)。在指定方向的相反方向(如水平容器的垂直方向),只是扩大了子节点的范围。

../../_images/containers_box.png

这些容器使用*比例*属性,用于设置*扩展*标记的子容器。

Grid Container

在网格布局中排列子控件(通过:ref:网格容器<class_GridContainer>,必须指定列的数量)。同时使用垂直和水平扩展标记。

../../_images/containers_grid.png

Margin Container

子控件被扩展到该控件的边界(通过:ref:边距容器<class_MarginContainer>)。根据主题配置,将在页边距上添加填充。

../../_images/containers_margin.png

Again, keep in mind that the margins are a Theme value, so they need to be edited from the constants overrides section of each control:

../../_images/containers_margin_constants.png

Tab Container

允许您将多个子控件堆叠在一起(通过:ref:选项卡容器<class_TabContainer>),只有*当前*可见。

../../_images/containers_tab.png

通过点击位于容器顶部的选项卡,来标记*当前*选项卡:

../../_images/containers_tab_click.gif

The titles are generated from the node names by default (although they can be overridden via TabContainer API).

在*选项卡容器*主题覆盖中,可以修改选项卡位置和*盒子样式*等内容。

Split Container

只接受一两个子控件,然后将它们与除数并排放置(通过:ref:水平分割容器<class_HSplitContainer>`和:ref:`垂直分割容器<class_VSplitContainer>)。同时考虑水平和垂直标记,以及*比例*。

../../_images/containers_split.png

可以拖动除数来改变两个子元素之间的大小关系:

../../_images/containers_split_drag.gif

PanelContainer

绘制*样式盒子*的简单容器,然后将子节点扩大到整个区域(通过:ref:面板容器<class_PanelContainer>,考虑*样式盒子*的边距)。它同时考虑水平和垂直尺寸标记。

../../_images/containers_panel.png

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

ScrollContainer

接受一个单独的子节点。如果这个节点比容器大,将添加滚动条以允许移动节点(通过:ref:滚动条容器<class_ScrollContainer>)。考虑垂直和水平尺寸标识,该行为可以在属性中的每个轴上打开或关闭。

../../_images/containers_scroll.png

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

../../_images/containers_center_pan.gif

在上面的例子中,使用此容器最常见的方法之一,是将*垂直盒子容器*作为子容器一起使用。

ViewportContainer

这是一个特殊的控件,它只接受单个*视口*节点作为子节点,它会像显示图像一样显示它(通过:ref:视口容器 <class_ViewportContainer>)。

Creating custom Containers

可以使用脚本轻松地创建自定义容器。下面是一个简单容器的例子,它适合于其矩形大小的子容器:

extends Container

func _notification(what):
    if (what==NOTIFICATION_SORT_CHILDREN):
        # Must re-sort the children
        for c in get_children():
            # Fit to own size
            fit_child_in_rect( c, Rect2( Vector2(), rect_size ) )

func set_some_setting():
    # Some setting changed, ask for children re-sort
    queue_sort()