Rustslint实现一个登录demo
目录
Rust+slint实现一个登录demo
系列文章目录
前言
本文章就是一个简单rust全栈编程的一个小小的示例供rust新手阅读学习。
一、为什么前端选择slint而不是Tauri或者其他GUI框架
下面是我AI出来的一张表
框架 | GUI 模式 | 渲染后端 | 性能优势 | 最佳适用场景 |
---|---|---|---|---|
egui | 即时模式 | wgpu/glow | 极高渲染帧率,实时响应 | 游戏工具、实时数据仪表盘、调试界面 |
Iced | 保留模式 (Elm) | wgpu/glow/tiny_skia | 良好的渲染性能,高效更新 | 通用桌面应用、工具软件 |
Slint | 保留模式 (DSL) | 自有高效渲染器 | 最低内存占用,最快启动 | 嵌入式系统、资源敏感型应用、Kiosk |
Tauri | Web (任何前端框架) | 系统 WebView | 高开发效率,安装包小 | 商业桌面应用、利用现有Web技术的项目 |
GTK-rs | 保留模式 (GTK) | Cairo/GTK | 原生外观,稳定 | 希望与 GNOME/Linux 桌面深度集成的应用 |
其是我选择slint的主要原因就是看重它的高性能和跨平台能力,对于手机或者树莓派这类内存敏感平台会更友好一些。
二、开发工具
这里我选择的是RustRover它对新手会友好一些,代码提示丰富,开发起来效率也会高一些。
使用slintGUI框架的话RustRover也有对应的插件,可以预览窗体效果
三、代码编写
项目结构
首先安装号rust的开发环境,具体怎么安装可以在网上寻找教程
在控制输入命令
cargo new slint-test
创建一个rust的项目
打开之后项目结构如下;新创建的项目不会有assets和ui这两个文件夹和build.rs文件,因为这是我自己创建的
前端代码编写
前端的代码我把它和rust分开了,方便项目管理,这里我创建了一个ui
文件夹,里面主要是放.slint文件也就是前端文件
import { VerticalBox, HorizontalBox, LineEdit, Button, CheckBox } from "std-widgets.slint";
import "../assets/fonts/Amble-Regular.ttf";
export component LoginWindow inherits Window {
default-font-family: "Amble";
preferred-width: 500px;
preferred-height: 400px;
title: "用户登录";
icon: @image-url("../assets/icons/windowlog.png");
in-out property <string> userName: "";
in-out property <string> passWord: "";
in-out property <bool> remember-me: false;
in-out property <string> message: "";
callback login();
// 1. 先把整个内容放进一个占满窗口的布局
VerticalLayout {
alignment: center; // 垂直居中
HorizontalLayout {
alignment: center; // 水平居中
// 2. 真正负责外观的卡片
Rectangle {
background: #ffffff;
border-radius: 8px;
drop-shadow-offset-x: 2px;
drop-shadow-offset-y: 2px;
drop-shadow-blur: 6px;
drop-shadow-color: #00000030;
width: 450px;
VerticalLayout {
spacing: 12px;
padding: 20px;
// 标题
Text {
text: "用户登录";
font-size: 24px;
color: #2c3e50;
font-weight: 700;
horizontal-alignment: center;
}
// 表单区域
VerticalLayout {
spacing: 10px;
width: 400px;
// 用户名输入
HorizontalLayout {
spacing: 10px;
height: 40px;
Text {
text: "用户名:";
width: 80px;
horizontal-alignment: right;
vertical-alignment: center;
}
LineEdit {
placeholder-text: "请输入用户名";
text <=> root.userName;
}
}
// 密码输入
HorizontalLayout {
spacing: 10px;
height: 40px;
Text {
text: "密码:";
width: 80px;
horizontal-alignment: right;
vertical-alignment: center;
}
LineEdit {
placeholder-text: "请输入密码";
text <=> root.passWord;
input-type: password;
}
}
// 记住我选项
CheckBox {
text: "记住登录状态";
checked <=> root.remember-me;
}
}
// 登录按钮
HorizontalLayout {
alignment: center;
Button {
text: "登 录";
clicked => {
root.login();
}
width: 120px;
height: 36px;
}
}
// 消息提示
Text {
color: #e74c3c;
height: 20px;
text <=> root.message;
}
}
}
}
}
}
在代码中有这样一句代码:
这里是我放置的字体文件;
import "../assets/fonts/Amble-Regular.ttf";
assets 文件夹主要就是放一些静态文件
目前主要是放一下图标和字体文件
后端开发编写
后端主要就是做了一个密码校验和一些简单的逻辑处理
slint::include_modules!(); // 导入编译生成的 UI 代码
use std::time::Duration;
fn main() -> Result<(), slint::PlatformError> {
let ui = LoginWindow::new()?;
// 加载保存的用户名和密码(示例中简单实现)
if let Some((user, pass)) = load_credentials() {
ui.set_userName(user.into());
ui.set_passWord(pass.into());
ui.set_remember_me(true);
}
let ui_handle = ui.as_weak();
ui.on_login(move || {
let ui = ui_handle.unwrap();
let username = ui.get_userName();
let password = ui.get_passWord();
let remember = ui.get_remember_me();
// 简单的验证逻辑
if username.is_empty() || password.is_empty() {
ui.set_message("用户名和密码不能为空".into());
return;
}
// 模拟网络请求延迟
slint::spawn_local({
let ui_weak = ui.as_weak();
async move {
// 模拟网络请求
async_std::task::sleep(Duration::from_secs(1)).await;
let success = username == "admin" && password == "123456";
ui_weak.upgrade_in_event_loop(move |ui| {
ui.set_message(if success {
if remember {
save_credentials(&username, &password);
} else {
clear_credentials();
}
"登录成功!".into()
} else {
"用户名或密码错误".into()
});
}).unwrap();
}
}).expect("程序内部错误!");
});
ui.run()
}
// 简单的凭证存储(实际应用中应该加密)
fn save_credentials(username: &str, password: &str) {
// 这里应该使用更安全的方式存储
println!("保存凭证: {}:{}", username, password);
}
fn load_credentials() -> Option<(String, String)> {
// 这里从安全存储中加载
Some(("admin".into(), "123456".into())) // 示例中硬编码
}
fn clear_credentials() {
println!("清除保存的凭证");
}
在代码开头有这样一句代码
slint::include_modules!();
这里是因为我在build.rs文件中进行了处理所有这里就不需要导入指定的slint文件
fn main() {
slint_build::compile("src/ui/login.slint").unwrap();
}
运行效果
打开RustRover 输入命令:cargo run
总结
以上就是今天要讲的内容,本文仅仅简单介绍了rust+slint的使用。rust是一门很好的语言没有GC不用担心对象跑飞。性能也和c和c++不相上下,却比他们更安全。