Slint 学习笔记
Slint 的应用架构如下图所示:
Slint 应用使用为 UI 设计的 Slint DSL 对 UI 进行描述。这些 UI 代码通过若干 .slint 文件构成,每个 .slint 文件中可以描述若干个组件,这些组件之间进行复用,并构造一个完整的 UI 界面。
为了展示 Slint 界面,需要通过 Slint 编译器将 .slint 文件编译为 Slint 的内部表示后原生运行。这个编译的过程可以在应用程序编译时完成,也可以在程序运行时再进行。
在运行时内部,按 .slint 描述的界面元素,构成一棵 UI 元素树,在进行渲染时便基于这个 UI 元素树进行。
Slint 使用的属性、回调、模型元素也在运行时内部维护。这些元素也是应用程序代码与 UI 之间沟通的桥梁。用户界面与应用程序逻辑的交互全部通过这几类元素完成。
基于最终的 UI 元素树可以计算得到每个像素值,这些值需要展示到显示设备上。这个计算每个像素值并向显示设备传输的过程便由渲染器实现。
为了相互用户的输入,需要与输入设备交互,并将这些交互封装为输入事件传入运行时,从而分发到对应的处理函数,并产生最终的交互。
Slint 中的一些关键概念、元素可概括如下:
- 定位与布局:Slint 中的坐标系为 x, y 两个坐标轴,x 轴从左侧的 0 向右侧增长,y 轴从顶部的 0 向下增长。元素的大小从元素树的最内层开始向外计算,元素的位置从元素树的最外层元素向内计算。
- 语法:
- 注释:// 单行注释 /* 可 /* 嵌套 */ 的块注释 */
- 标识符:由大小写字母、数组、下划线和减号构成,下划线会自动标准化为减号
- 类型
- 基本类型
- 结构体 export struct Player { name: string, score: int }
- 枚举 export enum CardSuit { clubs, diamonds, hearts, spades }
- 数组 [int], 在 for 循环中使用的数组即为模型
- 属性
- 权限修饰 private(deafult)/in/out/in-out
- 绑定(通过表达式)、双向绑定(<=>)
- 变更回调 changed bar => {}, 回调中修改值导致循环变化的代码属于未定义行为
- 函数
- 回调 可以通过 <=> 实现别名(类似双向绑定)
- 重复 for name[index] in model : id := Element {} // 整数model表示次数,数组model表示内部元素
- 条件 if condition: id := Element {}
- 动画 animate x {}
- 状态:states 声明状态,一次性设置多个属性;transition 在状态内部定义渐入/渐出动画
- 全局单例:export global X {} 在所有文件、逻辑代码中都可用
- 模块化
基于这些语法基础,即可构建一个 GUI 应用,但 Slint 自身提供了一些内置的回调等元素:
- 内置回调:所有元素都隐式实现了 init 回调,该回调会在元素实例化并将所有属性设置完成后调用。由于 init 的回调属于元素创建过程的一步骤,这一回调无法通过应用代码设置。
- 内置元素:
- Geometry: width, height, x, y, z(常量), absolute-position
- Layout: col, row, colspan, rowspan, horizontal-stretch, vertical-stretch, max-width, max-height, min-width, min-height, preferred-width, preferred-height
- Miscellaneous: ache-rendering-hint, dialog-button-role, opacity, visible
- Accessibility: accessible-role, accessible-checkable, accessible-checked, accessible-description, accessible-label, …
- Drop Shadow: drop-shadow-blur, drop-shadow-color, drop-shadow-offset-x, drop-shadow-offset-y
- …
- 内置枚举:…
- 内置函数:
- animation-tick() -> duration 返回单调递增的时间,可用于动画
- debug(…) 打印接收的若干参数
- 内置全局单例:Palette, TextInputInterface
- 内置命名空间:Colors, Key, Math
- 内置结构体:KeyEvent, KeyboardModifiers, Point, PointerEvent, PointerScrollEvent, StandardListViewItem, TableColumn
对于样式要求不高的应用,使用内置的小组件即可满足要求。