《Rust+Slint:跨平台GUI应用》第零章 入门
Rust的GUI开发常因编译体积大、终端窗口干扰等问题令人困扰。Slint作为专为Rust设计的声明式GUI工具包,通过4个核心文件(Cargo.toml/build.rs/main.rs/main.slint)即可实现简洁的桌面应用开发。该方案具有三大优势:1) 声明式语法简化UI开发;2) 自动隐藏终端窗口;3) 优化后编译体积仅约3MB。示例展示了一个基础计数器应用,包含数据绑定(属性自动更
你是否曾为 Rust 写 GUI 而头疼?要么依赖复杂的跨平台库,编译后体积大到离谱;要么配置步骤繁琐,写了几十行代码还看不到窗口;好不容易跑起来,终端窗口还跟 GUI 一起弹出来,显得格外不专业。
Slint 的出现,恰好踩中了这些痛点。作为一款专为 Rust 设计的声明式 GUI 工具包,它让你用极少的代码就能实现流畅的桌面应用,还能轻松控制编译体积、隐藏终端窗口。更重要的是,它的语法直观,数据绑定和事件处理逻辑几乎不用 “动脑”—— 就像搭积木一样简单。
本章不会讲枯燥的理论,只带你做一件事:用 4 个文件、不到 100 行核心代码,亲手编译出一个带计数器的 Windows GUI 程序。你不用关心复杂的底层渲染,不用调试诡异的链接器错误,跟着步骤复制粘贴,5 分钟后就能看到自己的第一个 Slint 应用跑起来。而这,只是 Slint 强大功能的冰山一角。
一、先搭好骨架:4 个核心文件搞定项目结构
要让 Slint 项目跑起来,无需复杂的目录嵌套,根目录下建 4 个文件就够了。每个文件各司其职,分工明确,后续维护时也能快速定位修改。
项目结构如下(直接复制到你的文件夹即可):
plaintext
Slint_exam/ # 你的项目根目录
├─ Cargo.toml # 管依赖:指定Slint版本+编译优化配置
├─ build.rs # 管构建:编译.slint文件+隐藏终端窗口
├─ src/
│ ├─ main.rs # 管逻辑:Rust入口,启动UI窗口
│ └─ main.slint # 管界面:用Slint语法画窗口、按钮和文本
二、填肉:逐个文件写代码(可直接复制运行)
1. Cargo.toml:依赖与优化 “一把抓”
这是项目的 “配置中心”,既要指定 Slint 的版本(1.14.1 稳定版),也要提前做好体积优化 —— 毕竟谁也不想自己的 GUI 程序编译后有几十 MB。
[package]
name = "Slint_exam"
version = "0.1.0"
edition = "2024"
# 运行时依赖
[dependencies]
slint = "1.14" # 运行时依赖,核心GUI库,1.14.1为稳定版
# 构建脚本依赖
[build-dependencies]
slint-build = "1.14.1" # 构建脚本依赖,版本必须与slint保持同步,避免兼容性问题
# --------------------------
# Release 模式基础优化配置,模式优化:让程序更小、更快
# --------------------------
[profile.release]
opt-level = "z" # 优先减小体积
lto = true # 开启链接时优化
codegen-units = 1 # 便于LTO优化
panic = "abort" # 移除panic展开代码
strip = "debuginfo" # 剥离调试信息
2. build.rs:悄悄帮你 “隐藏” 终端窗口
很多 Rust GUI 新手都会遇到一个问题:运行程序时,除了 GUI 窗口,还会弹出一个黑色的终端窗口。这个脚本的核心作用,就是在 Release 模式下自动去掉终端窗口,同时完成.slint 文件的编译。
fn main() {
// 第一步:把src/main.slint编译成Rust代码(生成绑定,让Rust能调用UI)
slint_build::compile("src/main.slint")
.expect("编译.slint文件失败!检查路径是否正确:src/main.slint");
// 第二步:仅Release模式下,添加Windows GUI链接器参数(关键!)
if std::env::var("PROFILE").unwrap_or_default() == "release" {
// 告诉编译器:这是一个GUI程序,不是控制台程序
println!("cargo:rustc-link-arg=/SUBSYSTEM:WINDOWS");
// 适配Rust的main函数入口(否则Windows会找不到启动函数)
println!("cargo:rustc-link-arg=/ENTRY:mainCRTStartup");
}
}
3. src/main.slint:画 UI
Slint 的精髓就在这里 —— 用声明式语法画界面,不用写一行渲染代码。你只需要告诉它 “我要一个窗口、两个按钮、一个文本”,以及它们的位置和交互逻辑,剩下的交给 Slint 处理。
// src/main.slint
import { Button } from "std-widgets.slint"; // 导入按钮组件
export component MainWindow inherits Window { // 窗口类继承Window类
title: "Slint 1.14.1 Simple Demo"; // 必须用export导出
width: 300px; // 宽度
height: 200px; // 高度
// 定义一个可被 Rust 访问的整数属性(计数器)
in_out property <int> count:0;
// 垂直布局
VerticalLayout {
spacing: 24px; // 间隔
padding: 32px; // 内边距
// 显示计数器
Text {
text: "Count: " + count; // 显示计数器
color: #2c3e50; // 颜色
font-size: 28px; // 字体大小
horizontal-alignment: TextHorizontalAlignment.center; // 水平居中
}
// 水平布局
HorizontalLayout {
alignment: LayoutAlignment.center; // 居中
spacing: 12px; // 间隔
Button { // 按钮
text: "-1"; // 按钮文本
width: 60px; // 宽度
clicked => { // 点击事件
root.count -= 1; // 减1
}
}
Button { // 按钮
text: "+1"; // 按钮文本
width: 60px; // 宽度
clicked => { // 点击事件
root.count += 1; // 加1
}
}
}
}
}
开发上面的slint代码是不是也很头痛?别怕,咱有工具。例如:在VSCode下,我们可以用“Slint language support”插件,安装了这个插件后,咱们就可以可视化的开发界面了,与惯用的IDE没啥两样。下图是在VSCode的扩展商店中找到Slint的截图,这里需要注意版本,如果你用的是“1.14.1”版本的slint,那么下面的插件也要选择适配“1.14.1”的。

4. src/main.rs:启动 UI 的 “开关”
这是整个程序的入口,作用很简单:创建 UI 窗口、初始化参数(比如把计数器默认值设为 5),然后启动事件循环(让窗口保持打开,等待用户点击)。
slint::include_modules!();
// 关键:为main函数声明返回类型 Result<(), slint::PlatformError>
fn main() -> Result<(), slint::PlatformError> {
// 1. 创建 UI 窗口实例
let window = MainWindow::new()?;
// 2. (可选)初始化计数器值(也可以在 .slint 中直接设置默认值)
window.set_count(5);
// 3. 启动 UI 事件循环(阻塞,直到窗口关闭)
window.run()
}
三、跑起来:3 步见证成果
不用复杂的配置,复制完上面的文件,跟着下面 3 步做,马上就能看到你的 GUI 程序。
- 打开命令行:进入项目根目录(Slint_exam 文件夹)。
- 编译 Release 版本:执行命令(Release 版才会隐藏终端窗口,体积也小):
cargo build --release - 找到并运行程序:编译完成后,去
target/release/文件夹下,找到slint_simple_demo.exe(如果改了项目名,就是你的项目名.exe),双击运行。
此时会弹出一个带计数器的窗口,点击 “+1”“-1” 按钮,中间的数字会实时变化,而且没有讨厌的终端窗口—— 恭喜你,第一个 Slint 程序跑通了!
注:在执行上面的编译(第2步)命令时,如果没有预先安装slint,或者是第一次使用并编译slint,cargo系统会下载近500个文件,请耐心等待!尽管我已经是安装过slint,省略了编译前的管理库下载,但也要耗费1分钟以上的时间,如下:
D:\rust_projects\Slint_exam>cargo build --release
Compiling Slint_exam v0.1.0 (D:\rust_projects\Slint_exam)
Finished `release` profile [optimized] target(s) in 1m 35s
这样编译完的文件如下:
D:\rust_projects\Slint_exam\target\release 的目录
2025/10/29 周三 10:28 <DIR> .
2025/10/29 周三 10:28 <DIR> ..
2025/10/28 周二 20:01 0 .cargo-lock
2025/10/28 周二 20:18 <DIR> .fingerprint
2025/10/28 周二 20:18 <DIR> build
2025/10/29 周三 10:27 <DIR> deps
2025/10/28 周二 20:01 <DIR> examples
2025/10/28 周二 20:01 <DIR> incremental
2025/10/29 周三 10:28 341 Slint_exam.d
2025/10/29 周三 10:28 3,172,864 Slint_exam.exe
2025/10/29 周三 10:28 1,855,488 Slint_exam.pdb
4 个文件 5,028,693 字节
这里要强调的是,如果我们没有在Cargo.toml进行“[profile.release]”的相关配置,那么生成的可执行文件Slint_exam.exe可能会达到15M左右。而经过我们优化后,可以看到编译完的Slint_exam.exe文件,只有3M大小。
注:如果您还想要在3M的基础上,继续大幅度缩减该可执行文件的大小,可以给笔者留言,笔者有更好的办法。
程序启动如下:

四、划重点:本章示例的 4 个核心知识点
别光顾着开心,这几个知识点是后续进阶的基础,先记牢:
| 核心特性 | 实现关键(本章用到的) |
|---|---|
| 数据绑定 | .slint 中用in-out property <int> count定义属性,Rust 用set_count修改,文本自动更新。 |
| 事件处理 | 按钮的clicked => { root.count += 1; }:一行代码绑定点击事件,不用 Rust 额外写逻辑。 |
| 隐藏终端窗口 | build.rs 中判断 Release 模式,添加/SUBSYSTEM:WINDOWS链接器参数。 |
| 体积优化 | Cargo.toml 的opt-level = "z"+lto = true,Release 版体积仅 3MB左右。 |
本章的计数器 demo,其实只用到了 Slint 的 “皮毛”。你有没有发现一些可以拓展的点?比如:
- 想让按钮点击时有动画效果?下一章我们会讲 Slint 的状态与动画,让 UI 从 “静态” 变 “动态”。
- 想把计数器的值存到本地,下次打开程序还在?后续会教你用 Rust 结合 Slint 做数据持久化。
- 觉得默认的按钮太丑?我们会介绍如何自定义组件样式,甚至用图片做按钮 ——Slint 的样式系统比你想象的灵活。
- 想在 Linux 或 macOS 上运行?别担心,下一章会讲跨平台适配,只需改几行配置,程序就能在三大桌面系统跑起来。
如果你已经迫不及待想给这个 demo 加新功能,比如加个 “重置为 0” 的按钮,或者让数字变色,不妨先自己试试。下一章,我们将从 “基础 UI” 走向 “进阶交互”,带你解锁 Slint 更强大的功能。
更多推荐



所有评论(0)