Skip to content

你使用 Slint 语言编写用户界面,并保存为扩展名为 .slint 的文件。

每个 .slint 文件定义一个或多个组件。这些组件声明了一个元素树。组件构成了 Slint 中组合的基础。利用它们,你可以构建自己可重用的 UI 控件集。你可以在另一个组件中以元素的形式使用每个已声明的组件(按其名称)。

下面是组件与元素的示例:

slint
component MyButton inherits Text {    color: black;    // ...}
export component MyApp inherits Window {    preferred-width: 200px;    preferred-height: 100px;    Rectangle {        width: 200px;        height: 100px;        background: green;    }    MyButton {        x:0;y:0;        text: "hello";    }    MyButton {        y:0;        x: 50px;        text: "world";    }}

MyButtonMyApp 都是组件。WindowRectangleMyApp 使用的内置元素。MyApp 还以两个独立元素的形式重用了 MyButton 组件。

元素具有属性,你可以为它们赋值。上面的示例将字符串常量 "hello" 赋值给第一个 MyButtontext 属性。你也可以赋值整个表达式。当表达式所依赖的任何属性发生变化时,Slint 会重新计算该表达式,这使得用户界面具有响应式特性。

你可以使用 := 语法为元素命名:

slint
component MyButton inherits Text {    // ...}
export component MyApp inherits Window {    preferred-width: 200px;    preferred-height: 100px;
    hello := MyButton {        x:0;y:0;        text: "hello";    }    world := MyButton {        y:0;        text: "world";        x: 50px;    }}

Note

名称必须是有效的 标识符

一些元素也可以通过预定义的名称访问:

  • root 指代组件的最外层元素。
  • self 指代当前元素。
  • parent 指代当前元素的父元素。

这些名称是保留的,你不能重新定义它们。

注释

注释是 Slint 编译器忽略的代码行。它们用于解释代码或临时禁用代码。

单行注释

单行注释以 // 开头,以换行符结束。

slint
// Amazing text! This is a comment

多行注释

多行注释以 /* 开头、*/ 结束,并以换行符结束。

slint
/*    This is a multi line comment.    It can span multiple lines.*/

元素与组件

Slint 语言的核心部分是元素和组件。从技术上讲它们是相同的,因此一旦你知道如何声明和使用其中之一,你也就知道了另一个。元素是构成 Slint 语言的基本构件,而组件(也称为控件)是由多个元素和属性组合而成的更大单元。

如果你来自其他语言(例如 HTML 或 React),你可能习惯于使用开闭标签以及自闭合标签。

html
<!-- opening and closing tag --><Button>Hello World</Button> <!-- self closing tag --><img/>

Slint 简单地提供了一种声明项的方式:使用 element-name 后跟一对花括号 {},其中包含该元素的属性。

slint
// validText {}
Text {}// Valid, but considered bad Slint practiceText{}
// Not valid due to terminating semicolonText {};

Note

Slint 工具链提供了一个代码格式化器,用于强制实施被认为是良好实践的格式。

如果你是编程新手,可以与其他开发者讨论你不喜欢的一些代码格式方面的话题,由此结交朋友。这是开发者们喜爱并欣赏的一种闲聊方式。

根元素

slint
component MyApp {    Text {        text: "Hello World";        font-size: 24px;    }}

要成为有效的 Slint 文件,根元素必须是一个组件。然后在组件内部你可以声明任意数量的元素。这将在后面更详细地解释,此时理解它并不重要。

属性

属性是赋给元素的值。它们使用 property-name: value; 语法进行设置。

标识符

标识符可以由字母(a-zA-Z)、数字(0-9)、下划线(_)或短横线(-)组成。 它们不能以数字或短横线开头(但可以以下划线开头)。 下划线会被标准化为短横线。这意味着下面两个标识符是相同的:foo_barfoo-bar

条件元素

if 构造仅在给定条件为真时实例化元素。 语法为 if condition : id := Element { ... }

slint
export component Example inherits Window {    preferred-width: 50px;    preferred-height: 50px;    if area.pressed : foo := Rectangle { background: blue; }    if !area.pressed : Rectangle { background: red; }    area := TouchArea {}}

模块

.slint 文件中声明的组件可以通过导出和导入的方式在其他 .slint 文件中作为元素使用。

默认情况下,在 .slint 文件中声明的每个类型都是私有的。export 关键字会改变这一点。

slint
component ButtonHelper inherits Rectangle {    // ...}
component Button inherits Rectangle {    // ...    ButtonHelper {        // ...    }}
export { Button }

在上面的示例中,Button 可被其他 .slint 文件访问,但 ButtonHelper 不行。

也可以仅为了导出的目的更改名称,而不影响其内部使用:

slint
component Button inherits Rectangle {    // ...}
export { Button as ColorButton }

在上面的示例中,Button 不能从外部访问,而是以 ColorButton 这个名称提供。

为方便起见,导出组件的第三种方式是直接将其声明为已导出:

slint
export component Button inherits Rectangle {    // ...}

类似地,可以导入从其他文件导出的组件:

slint
import { Button } from "./button.slint";
export component App inherits Rectangle {    // ...    Button {        // ...    }}

如果两个文件以相同名称导出一个类型,你可以在导入时为其分配一个不同的名称:

slint
import { Button } from "./button.slint";import { Button as CoolButton } from "../other_theme/button.slint";
export component App inherits Rectangle {    // ...    CoolButton {} // from other_theme/button.slint    Button {} // from button.slint}

元素、全局变量和结构体都可以被导出和导入。

也可以导出从其他文件导入的全局变量(参见 全局单例):

slint
import { Logic as MathLogic } from "math.slint";export { MathLogic } // known as "MathLogic" when using native APIs to access globals

模块语法

支持以下导入类型的语法:

slint
import { MyButton } from "module.slint";import { MyButton, MySwitch } from "module.slint";import { MyButton as OtherButton } from "module.slint";import {    MyButton,    /* ... */,    MySwitch as OtherSwitch,} from "module.slint";

支持以下导出类型的语法:

slint
// Export declarationsexport component MyButton inherits Rectangle { /* ... */ }
// Export listscomponent MySwitch inherits Rectangle { /* ... */ }export { MySwitch }export { MySwitch as Alias1, MyButton as Alias2 }
// Re-export types from other moduleexport { MyCheckBox, MyButton as OtherButton } from "other_module.slint";
// Re-export all types from other module (only possible once per file)export * from "other_module.slint";

组件库

将代码库拆分为单独的模块文件可以促进重用,并通过允许你隐藏辅助组件来改善封装。这在你项目的自有目录结构中可以很好地工作。要在项目之间共享组件库而不硬编码其相对路径,请使用组件库语法:

slint
import { MySwitch } from "@mylibrary/switch.slint";import { MyButton } from "@otherlibrary";

在上面的示例中,MySwitch 组件将从名为 mylibrary 的组件库导入,Slint 会在其中查找 switch.slint 文件。因此 mylibrary 必须声明为指向一个目录,以便后续能够成功查找到 switch.slintMyButton 将从 otherlibrary 导入。因此 otherlibrary 必须声明为指向一个导出 MyButton.slint 文件。

每个库(文件或目录)的路径必须在编译时单独定义。 使用以下方法之一来帮助 Slint 编译器将库解析为磁盘上的正确路径:

slint_target_sources(my_application    ui/main.slint    LIBRARY_PATHS        material=${CMAKE_CURRENT_SOURCE_DIR}/material-1.0/material.slint)

cmake

  • build.rs 中,调用 with_library_paths 以提供从库名到路径的映射。例如:
rust
// build.rsfn main() {    let manifest_dir = std::path::PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap());    let library_paths = std::collections::HashMap::from([(        "example".to_string(),        manifest_dir.join("third_party/example/ui/lib.slint"),    )]);    let config = slint_build::CompilerConfiguration::new().with_library_paths(library_paths);    slint_build::compile_with_config("ui/main.slint", config).unwrap();}
  • 使用 LoadFileOptions 中的 loadFile 提供 libraryPaths 映射。例如:
javascript
let ui = slint.loadFile("/path/to/main.slint", {    libraryPaths: {        "material": "/path/to/material-1.0/material.slint"    }});
  • 使用 load_file 提供 library_paths 字典。例如:
python
ui = slint.load_file(    "/path/to/main.slint",    library_paths={        "material": "/path/to/material-1.0/material.slint"    },)
  • 通过命令行调用 slint-viewer 时,为每个组件库传递 -Lmylibrary=/path/to/my/library
  • 使用 VS Code 扩展时,使用 Slint: Library Paths 设置来配置 Slint 扩展的库路径。示例如下:
json
  "slint.libraryPaths": {    "mylibrary": "/path/to/my/library",    "otherlibrary": "/path/to/otherlib/index.slint",},

这也可以在提交到你仓库中的 .vscode/settings.json 文件中进行编辑。 相对路径是相对于工作区根目录解析的。

  • 对于其他编辑器,可以将它们配置为像 slint-viewer 那样向 slint-lsp 传递 -L 参数。

基于 MIT 协议发布