当前位置: 首页 > news >正文

Rust Floem UI 框架使用简介

文章目录

  • 开始使用
    • 创建一个新的 Rust 项目
    • Hello World
    • 计数器应用
    • 响应式
    • 动作
    • 后记

之前一篇博客Rust 开发的一些GUI库提到了floem库,今天我决定试用了一下,根据官网文档,食用使用方式如下:
floem

开始使用

让我们通过一个简单的项目来快速了解 Floem 的基础知识。

创建一个新的 Rust 项目

cargo new floem-app

添加 Floem 依赖

cd floem-app
cargo add floem

Hello World

在你的 main.rs 文件中,写入以下内容:

fn main() {floem::launch(|| "Hello, World!");
}

然后运行 cargo run,你将在 Floem 窗口中看到你的第一个 hello world。

看起来很简单,对吧?如果你查看 floem::launch 的定义,会发现它接收一个返回 IntoView 的闭包。如果你熟悉 Rust,IntoView 是一个 trait,包含方法 into_view,可以将实现该 trait 的类型转换为 Floem View。Floem View 是 Floem 的核心,可以是文本标签、按钮、文本输入框或滚动视图等。Floem 为 &str 类型内部实现了 IntoView,所以我们可以直接返回 “Hello, World!” 作为 IntoView

现在让我们深入一个更复杂的例子:计数器应用。

计数器应用

我们将创建一个非常简单的计数器,显示当前计数值,并有一个递增按钮和一个递减按钮。

在 main.rs 中写入以下内容:

use floem::{views::button, IntoView};fn app_view() -> impl IntoView {("Value: ",button("Increment"),button("Decrement"),)
}fn main() {floem::launch(app_view);
}

运行后,你应该能看到 "Value: " 和两个巨大的 “Increment” 和 “Decrement” 按钮。

让我们通过添加一些“样式”来改进它:

use floem::{views::{button, Decorators},IntoView,
};fn app_view() -> impl IntoView {("Value: ",(button("Increment"), button("Decrement")).style(|s| s.flex_row().gap(6)),).style(|s| s.flex_col().gap(6).items_center())
}fn main() {floem::launch(app_view);
}

再次运行后,你会发现布局变得更合理了。在 Floem 中,视图通过 style 方法进行样式设置,该方法由 floem::views::Decorators 提供给所有实现了 IntoView 的类型。所以记得先导入该 trait,否则 Rust 编译器会报错。

Floem 的样式是通过 Taffy crate 实现的 Rust 版 Flexbox。如果你熟悉 Flexbox,会发现很多类似的地方。如果不熟悉,网上有很多关于 Flexbox 的教程,这些知识也适用于 Floem 样式。

响应式

但现在点击按钮还没有任何效果,因为还没有可变的值被显示或改变。那如何在 Floem 中实现响应式呢?

Signal (信号)是 Floem 响应式的基础。如果你熟悉 Solidjs 或 Leptos,这里的 signal 与那些框架类似。简单来说,如果你更新了一个 Signal 的值,所有“监听”该 signal 的内容都会收到通知,并根据更新触发相应操作。在我们的计数器例子中,我们希望计数值在 UI 中被更新。让我们创建一个信号 signal。

use floem::{prelude::create_rw_signal,views::{button, dyn_view, Decorators},IntoView,
};fn app_view() -> impl IntoView {let counter = create_rw_signal(0);(dyn_view(move || format!("Value: {}", counter)),(button("Increment"), button("Decrement")).style(|s| s.flex_row().gap(6)),).style(|s| s.flex_col().gap(6).items_center())
}fn main() {floem::launch(app_view);
}

你会注意到我们创建了一个计数器信号 signal,并用闭包包裹了值的显示,通过 dyn_view 格式化计数器的值。你可能会问,为什么不用 format!("Value: {}", counter),毕竟 String 也实现了 IntoView。这样写虽然能编译通过,但会失去响应式。

解释如下:

与 Reactjs 等框架不同,视图创建函数只会被调用一次。因此 format!("Value: {}", counter) 也只会被调用一次,并且只会获取计数器的初始值 0。即使之后更新了计数器 signal 的值,Value: 0 也不会更新,因为不会再次运行。

所以 Floem 的响应式依赖于闭包,每当 signal 更新时,闭包会被反复执行。这带来了 Floem 的“细粒度响应式”特性,UI 不需要与之前的状态做 diff,只会更新需要更新的部分,无论视图树多深。即使计数值显示在很深的嵌套中,也能“直接”更新 UI,仅仅是那个文本标签部分,无需从根遍历视图树。

这也形成了 Floem 响应式的基本规则:如果你希望某些内容被更新,需要使用闭包。如果你在使用 Floem 时遇到某些内容没有更新,首先要检查“是不是用了闭包”。

动作

但按钮依然没有任何作用,因为我们还没有让按钮点击去更新计数器 signal。如果你这样写:

use floem::{prelude::create_rw_signal,views::{button, dyn_view, Decorators},IntoView,
};fn app_view() -> impl IntoView {let mut counter = create_rw_signal(0);(dyn_view(move || format!("Value: {}", counter)),(button("Increment").action(move || counter += 1),button("Decrement").action(move || counter -= 1),).style(|s| s.flex_row().gap(6)),).style(|s| s.flex_col().gap(6).items_center())
}fn main() {floem::launch(app_view);
}

我们只需在按钮上调用 action 方法,递增或递减计数器 signal 的值。现在你就有了一个可用的计数器示例。

本教程到此结束。想了解更多 Floem,可以查看我们仓库中的 示例,或阅读 API 文档。

后记

在Windows系统中,默认生成的GUI界面在运行的时候会弹出命令行窗口(控制台),要去掉这个窗口,可以通过以下cargo命令实现:

  • 对于debug版:
cargo rustc -- -Clink-args="/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup"
  • 对于release版:
cargo rustc --release -- -Clink-args="/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup"

相关文章:

  • 【HarmonyOS 5】 影视与直播详以及 开发案例
  • Kafka深度解析与原理剖析
  • 实现单例模式的常见方式
  • 虚实共生时代的情感重构:AI 恋爱陪伴的崛起、困局与明日图景
  • React从基础入门到高级实战:React 实战项目 - 项目一:在线待办事项应用
  • windows server2019 不成功的部署docker经历
  • 使用 Docker Compose 安装 PostgreSQL 16
  • SSH/RDP无法远程连接?腾讯云CVM及通用服务器连接失败原因与超全排查指南
  • 腾讯云V3签名
  • select、poll、epoll 与 Reactor 模式
  • vue-router路由问题:可以通过$router.push()跳转,但刷新后又变成空白页面
  • vue3+ts实现百度地图鼠标绘制多边形
  • Excel处理控件Aspose.Cells教程:使用 C# 从 Excel 进行邮件合并
  • 基于51单片机的车内防窒息检测报警系统
  • springboot mysql/mariadb迁移成oceanbase
  • uniapp实现的简约美观的星级评分组件
  • 仓库自动化搬运:自动叉车与AGV选型要点及核心技术解析
  • 各种排序算法的再整理
  • 可穿戴设备:健康监测的未来之眼
  • 我认为STM32输入只分为模拟输入 与 数字输入
  • 网站一般用什么软件做/宁波seo关键词如何优化
  • 来宾建设工程造价网站/外贸seo推广公司
  • 网站建设如何定位/百度查重工具
  • 江苏优化网站/江苏网站推广公司
  • 高端网站建设的公司/百度口碑官网
  • 网页设计实训报告不足/湖南关键词优化首选