目录

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文件,因为这是我自己创建的
https://i-blog.csdnimg.cn/direct/351c4d22c26b4cf8946024fead88be52.png

前端代码编写

前端的代码我把它和rust分开了,方便项目管理,这里我创建了一个ui文件夹,里面主要是放.slint文件也就是前端文件
https://i-blog.csdnimg.cn/direct/eb0d5e62bbd44c1bb4ac93570c2fb41c.png

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 文件夹主要就是放一些静态文件
目前主要是放一下图标和字体文件
https://i-blog.csdnimg.cn/direct/2bcf4f5d41de434f84b28a38eb3e76f5.png

后端开发编写

后端主要就是做了一个密码校验和一些简单的逻辑处理

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文件
https://i-blog.csdnimg.cn/direct/45dccddb6cf34bb3bc6a8bb7e36a481e.png

fn main() {
    slint_build::compile("src/ui/login.slint").unwrap();
}

运行效果

打开RustRover 输入命令:cargo run

https://i-blog.csdnimg.cn/direct/3d09654afd5c40e4b7b48425a7923d01.png


总结

以上就是今天要讲的内容,本文仅仅简单介绍了rust+slint的使用。rust是一门很好的语言没有GC不用担心对象跑飞。性能也和c和c++不相上下,却比他们更安全。