slint是什么

一个ui框架,因为依赖是可选的,并且slint可以编译为原生代码.
所以甚至可以跑在没有系统的stm32上,
非常适合嵌入式.
ui部分类似qt写法,后端可以用rust, cpp和js.
不学qt的主要原因是想用用rust

不过slint官网没有中文文档,
试过翻译但是效果不尽人意,看过了翻译还会忘掉.
所以做做笔记还是有点必要的.
有参考机翻,如有疏漏错误,欢迎补充.

单位

  • px: 逻辑像素.在任何设备上, px大小相同,看起来的大小也相同. slint会自动根据ppi转换.
  • phx: 物理像素. 单纯的几个像素点.
  • %: 相对父元素的比例.没有父元素时不能使用.

容器

这里列举一些常用的简单的容器.

  • Rectangle: 空盒子,类似html div.
  • TouchArea: 可触控区域.
  • FocusScope
  • Flickable
  • VerticalLayout/HorizontalLayout: 子项沿垂直/水平放置.
  • GridLayout:子项放置在由列和行组成的网格中.
    • Row: 为GridLayout的子元素,表示行.
    • 也可以不用row, 而直接列出所有子元素.会自动排版.

容器的一些通用属性

  • min-width: 允许的最小长度.下面三个同理
  • min-height
  • max-width
  • max-height
  • preferred-width: 首选大小. 默认为子元素中width较大的那个.
  • preferred-height
  • spacing: 子项之间的间距
  • padding
  • [private|public] [in|out|in-out] property < T > var-name
    • in: 输入参数
    • out: 只可由组件修改其值
    • in-out: 任意读写
    • 例如 private in-out property < Text> name;

用于布局的属性

  • alignment
    • stretch: 尽量拉伸
    • start
    • end
    • center
    • space-between: 元素之间留空
    • space-around: 元素之间和元素最左端和最右端留空.
  • horizontal-stretch: int
    按比例拉伸. 比如三个元素的h-stretch为3, 2, 1,那大小也是等比拉伸.

循环语法

上示例更好懂:

1
2
3
for t in [ "Hello", "World", "!" ] : Text {
text: t;
}

缺省元素

可以在容器内使用@children表示从外部传入的组件.

1
2
3
4
5
6
component BoxWithLabel inherits GridLayout {
Row { @children }
}
BoxWithLabel {
Rectangle { background: blue; height: 50px;}
}

字体

e.g.
default-font-family: "Noto Sans";

副作用和纯函数

slint中运行时不改变值的函数称为纯函数.
基于纯函数的特性,slint可以做到惰性求值.
如果不是纯函数则会导致’副作用’,比如改变变量状态.
声明purity以标注函数为纯函数:

1
2
pure callback foo() -> int;
pure function bar(x: int) -> int { return x + foo(); }

翻译

最基本的格式化字符串功能:

1
2
3
4
5
6
property <string> name;
property <int> score;
Text {
text: @tr("Hello, {}", name);
text: @tr("Hello {0}, you have one point" | "Hello {0}, you have {n} point" % score, name);
}

i18n的部分略

绑定

单向绑定:

1
2
3
4
5
Button {
property <int> counter: 3;
clicked => { self.counter += 3 }
text: self.counter * 2;
}

双向绑定:
<=>两边值始终相等

1
2
3
4
5
6
7
in property<brush> rect-color <=> r.background;
in property rect-color2 <=> r.background;
r:= Rectangle {
width: parent.width;
height: parent.height;
background: blue;
}