Slint 学习笔记

Slint 的应用架构如下图所示:

alt

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

对于样式要求不高的应用,使用内置的小组件即可满足要求。