Skip to content

定位与布局

所有可视化元素都显示在窗口中。x 和 y 属性存储元素相对于其父元素的坐标。 Slint 通过把父元素的位置加到元素自身位置上来确定元素的绝对位置。 如果父元素本身还有父元素,那么也会一并加上。这个计算会一直持续到最顶层元素。

width 和 height 属性存储可视化元素的尺寸。

你可以通过两种方式放置元素来创建完整的图形用户界面:

  • 显式地——通过设置 x、y、width 和 height 属性。
  • 自动地——通过使用布局元素。

对于元素很少的静态场景,显式定位非常合适。布局适合复杂的用户界面, 并有助于创建可缩放的界面。布局元素表达元素之间的几何关系。

下面的示例把两个矩形放入窗口,一个蓝色、一个绿色。绿色矩形是蓝色的子元素:

// Explicit positioning
export component Example inherits Window {
width: 200px;
height: 200px;
Rectangle {
x: 100px;
y: 70px;
width: parent.width - self.x;
height: parent.height - self.y;
background: blue;
Rectangle {
x: 10px;
y: 5px;
width: 50px;
height: 30px;
background: green;
}
}
}
slint

两个矩形的位置以及内部绿色矩形的尺寸都是固定的。 外层蓝色矩形的尺寸通过 width 和 height 属性的绑定表达式自动计算。 计算结果使左下角与窗口的角对齐——每当窗口的 width 和 height 变化时,它都会更新。

为任何几何属性指定显式值时,Slint 要求你给数字附加单位。你可以在两种不同的单位之间选择:

  • 逻辑像素,使用 px 单位后缀。这是推荐的单位。
  • 物理像素,使用 phx 单位后缀

逻辑像素会根据你的系统所配置的设备像素比自动缩放。 例如,在现代化的高 DPI 显示器上设备像素比可能是 2,因此每个逻辑像素占据 2 个物理像素。 在较旧的屏幕上,用户界面无需任何适配即可缩放。

你还可以把 width 和 height 属性指定为 % 百分比单位,它相对于父元素应用。 例如 width: 50% 表示父元素 width 的一半。

x 和 y 属性的默认值会把元素居中于其父元素内。

width 和 height 的默认值取决于元素的类型。诸如 Image、Text 以及大多数控件之类的元素, 会根据其内容自动确定尺寸。以下元素没有内容,默认填满其父元素:

  • Rectangle
  • TouchArea
  • FocusScope
  • Flickable
  • SwipeGestureHandler
  • ScaleRotateGestureHandler

布局也默认填满父元素,无论其自身的首选尺寸如何。 其他元素(包括不以某个基类为父类的自定义元素)默认使用其首选尺寸。

你可以用 preferred-width 和 preferred-height 属性指定元素的首选尺寸。

当未显式设置时,首选尺寸取决于子元素,是那些未设置 x 和 y 属性的子元素中, 具有较大首选尺寸的那个子元素的首选尺寸。 因此首选尺寸是从子元素向父元素计算得到的,就像其他约束(最大和最小尺寸)一样, 除非被显式覆盖。

一个特殊情况是用 100% 作为值,把首选尺寸设为父元素的尺寸。 例如,这个组件默认使用父元素的尺寸:

export component MyComponent {
preferred-width: 100%;
preferred-height: 100%;
// ...
}
slint

Slint 提供了多种布局元素,可自动计算其子元素的位置和尺寸:

  • VerticalLayout / HorizontalLayout:子元素沿垂直或水平轴放置。
  • GridLayout:子元素放置在由列和行组成的网格中。

你还可以嵌套布局来创建复杂的用户界面。

你可以使用不同的约束来调整自动定位,以适应你用户界面的设计。 每个元素都有最小尺寸、最大尺寸和首选尺寸。用以下属性显式设置这些值:

  • min-width
  • min-height
  • max-width
  • max-height
  • preferred-width
  • preferred-height

任何指定了 width 和 height 的元素在布局中具有固定尺寸。

当布局中有多余空间时,元素可以沿布局轴拉伸。你可以用以下属性控制元素与其兄弟元素之间的拉伸系数:

  • horizontal-stretch
  • vertical-stretch

值为 0 表示元素完全不拉伸。如果所有元素的拉伸系数都为 1, 它们会等量拉伸。

这些约束属性的默认值可能取决于元素的内容。 如果元素的 x 或 y 未设置,这些约束也会自动应用到父元素。

所有布局元素都有以下公共属性:

  • spacing:控制子元素之间的间距。
  • padding:指定布局内的内边距,即元素与布局边界之间的空间。

如需更细粒度的控制,你可以把 padding 属性拆分为布局各边的属性:

  • padding-left
  • padding-right
  • padding-top
  • padding-bottom

VerticalLayout 和 HorizontalLayout 元素把其子元素放置在一列或一行中。 默认情况下,它们会拉伸或收缩以占据全部空间。你可以按需调整元素的对齐方式。

下面的示例把蓝色和黄色矩形排成一行,并在 200 逻辑像素的 width 上均匀拉伸:

// Stretch by default
export component Example inherits Window {
width: 200px;
height: 200px;
HorizontalLayout {
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
}
slint

另一方面,下面的示例指定矩形对齐到布局的起始端(视觉上的左侧)。 这样就不会拉伸,而是让矩形保留其指定的最小宽度:

// Unless an alignment is specified
export component Example inherits Window {
width: 200px;
height: 200px;
HorizontalLayout {
alignment: start;
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
}
slint

下面的示例嵌套两个布局以构成更复杂的场景:

export component Example inherits Window {
width: 200px;
height: 200px;
HorizontalLayout {
// Side panel
Rectangle { background: green; width: 10px; }
VerticalLayout {
padding: 0px;
//toolbar
Rectangle { background: blue; height: 7px; }
Rectangle {
border-color: red; border-width: 2px;
HorizontalLayout {
Rectangle { border-color: blue; border-width: 2px; }
Rectangle { border-color: green; border-width: 2px; }
}
}
Rectangle {
border-color: orange; border-width: 2px;
HorizontalLayout {
Rectangle { border-color: black; border-width: 2px; }
Rectangle { border-color: pink; border-width: 2px; }
}
}
}
}
}
slint

以百分比给出的 width 或 height 相对于父元素: width: 50%; 是 width: parent.width * 50%; 的简写。 参见语言参考中的几何。

如果指定了元素的 width 或 height,则按该值确定尺寸,否则将其设为最小尺寸—— 该最小尺寸由 min-width 或 min-height 属性设置,或由内部布局的最小尺寸决定,取较大者。

元素根据对齐方式放置。只有当布局的 alignment 属性为 LayoutAlignment.stretch(默认值)时, 元素的尺寸才会大于最小尺寸。

这个示例展示了不同的对齐可能性:

export component Example inherits Window {
width: 300px;
height: 200px;
VerticalLayout {
HorizontalLayout {
alignment: stretch;
Text { text: "stretch (default)"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
HorizontalLayout {
alignment: start;
Text { text: "start"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
HorizontalLayout {
alignment: end;
Text { text: "end"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
HorizontalLayout {
alignment: start;
Text { text: "start"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
HorizontalLayout {
alignment: center;
Text { text: "center"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
HorizontalLayout {
alignment: space-between;
Text { text: "space-between"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
HorizontalLayout {
alignment: space-around;
Text { text: "space-around"; }
Rectangle { background: blue; min-width: 20px; }
Rectangle { background: yellow; min-width: 30px; }
}
}
}
slint

当 alignment 设置为 stretch(默认值)时,元素先按其最小尺寸确定尺寸, 然后根据用 horizontal-stretch 和 vertical-stretch 属性设置的拉伸系数, 按比例在各元素之间共享多余空间。拉伸后的尺寸不会超过最大尺寸。 拉伸系数是浮点数。具有默认内容尺寸的元素通常默认为 0, 而默认使用其父元素尺寸的元素默认为 1。 拉伸系数为 0 的元素保持其最小尺寸,除非所有其他元素的拉伸系数也为 0,或达到了它们的最大尺寸。 元素自身的拉伸系数是其自身与其子元素中最小的那个。 在元素上设置 horizontal-stretch 或 vertical-stretch 可覆盖该值。

示例:

export component Example inherits Window {
width: 300px;
height: 200px;
VerticalLayout {
// Same stretch factor (1 by default): the size is divided equally
HorizontalLayout {
Rectangle { background: blue; }
Rectangle { background: yellow;}
Rectangle { background: green;}
}
// Elements with a bigger min-width are given a bigger size before they expand
HorizontalLayout {
Rectangle { background: cyan; min-width: 100px;}
Rectangle { background: magenta; min-width: 50px;}
Rectangle { background: gold;}
}
// Stretch factor twice as big: grows twice as much
HorizontalLayout {
Rectangle { background: navy; horizontal-stretch: 2;}
Rectangle { background: gray; }
}
// All elements not having a maximum width have a stretch factor of 0 so they grow
HorizontalLayout {
Rectangle { background: red; max-width: 20px; }
Rectangle { background: orange; horizontal-stretch: 0; }
Rectangle { background: pink; horizontal-stretch: 0; }
}
}
}
slint

VerticalLayout 和 HorizontalLayout 也可以包含 for 或 if 表达式:

export component Example inherits Window {
width: 200px;
height: 50px;
HorizontalLayout {
Rectangle { background: green; }
for t in [ "Hello", "World", "!" ] : Text {
text: t;
}
Rectangle { background: blue; }
}
}
slint

GridLayout 把元素摆放在网格中。 每个元素都会获得 row、col、rowspan 和 colspan 属性。 你既可以使用 Row 子元素,也可以显式设置 row 属性。 这些属性可以在运行时更改,网格布局中也支持 for 和 if。

这个示例使用 Row 元素

export component Foo inherits Window {
width: 200px;
height: 200px;
GridLayout {
spacing: 5px;
Row {
Rectangle { background: red; }
Rectangle { background: blue; }
}
Row {
Rectangle { background: yellow; }
Rectangle { background: green; }
}
}
}
slint

这个示例使用 col 和 row 属性:

export component Foo inherits Window {
width: 200px;
height: 150px;
GridLayout {
spacing: 0px;
Rectangle { background: red; }
Rectangle { background: blue; }
Rectangle { background: yellow; row: 1; }
Rectangle { background: green; }
Rectangle { background: black; col: 2; row: 0; }
}
}
slint

@children 占位符控制组件把其使用处的子元素放置在何处; 参见语言参考中的容器组件。


© 2026 SixtyFPS GmbH