我的 Rust GUI 开发之旅
2022-1-20 18:12:0 Author: mp.weixin.qq.com(查看原文) 阅读量:113 收藏

11 月 30 日晚上,我有几个小时的空闲时间,萌生了为 Relm4[1] 编写一个小的 advent(降临节) 日历示例应用程序的想法[2]因为时间紧迫,我想按计划进行,必须非常快地实施。这让我产生了利用 Rust 进行 GUI 实现加速运行的机会。毕竟,许多人不会认为 Rust 是快速 GUI 开发的好选择。

对于那些不熟悉降临节日历的人:降临节是圣诞节前的这段时间,或者更准确地说是从 12 月 1 日到圣诞节,降临节日历每天都有一扇门。每扇门后面通常都有一个小礼物、一句话或类似的东西。它们在许多国家(至少在德国)很受欢迎,并且通常包含糖果或玩具。见 DuckDuckGo 上的图片[3]

找出最佳策略

我发现从 speedrunning 的角度看 GUI 开发非常有趣。它让我更加了解我浪费时间的部分以及我非常快的部分。从我的错误中吸取教训,我认为我可以改进我在未来项目中的策略以及我的生产力。

计划

在开始处理 GUI 应用程序之前,你需要了解 UI 应该是什么样子。你越准确地知道自己想要什么,以后实现 UI 就越容易。

对我来说,查看其他应用程序的布局而不是提出全新的东西可以节省大量时间。在这种情况下,我从 libadwaita “flap” 演示中选择了一个布局,它有一个简单的可扩展侧边栏,允许你选择活动页面,类似于浏览器中的选项卡,但采用垂直布局。

libadwaita demo flap example

寻找最佳小部件

由于我想节省时间,我犯了一个错误,只是选择了听起来像是在做正确事情的小部件。但是,在 Speedrun 的过程中,我意识到我可以使用更好、更简单的小部件。

例如,我尝试使用 ViewSwitcherBar[4] 小部件作为侧边栏的一部分。然而,正如名称和文档所暗示的那样,它只是水平的,并不打算在侧边栏中使用。这导致我多次重构我的 UI 的某些部分,这花费了一些时间,尽管 Relm4 使重构 UI 变得非常容易和快速。

这张图片显示了一个早期版本,它有一个有效的侧边栏,但它看起来不正常,也不能真正识别为侧边栏。如果我之前知道有一个专门用于此目的的 StackSidebar[5] 小部件,我就节省了很多时间。

Work in progress image 1

我从中学到的是花更多的时间来选择最好的小部件。文档始终是一个很好的资源,如果我仔细研究它们,GTK4 和 libadwaita 的演示应用程序也会对我有所帮助。当然,更多的经验也会有很大帮助,并且不出所料,在 speedrun 过程中尝试新事物并没有变得非常快。

快捷方式

快捷键是游戏中几乎所有 speedrun 的重要组成部分。它们可以节省几毫秒到几个小时的时间。GUI 开发也是如此。了解正确的工具可以跳过通常需要更多时间才能完成的部分,从而显着加快你的工作流程。

编译器错误

使用 Rust 的一个好处是我经常认为理所当然的类型系统和所有权规则,可以在编译时防止很多错误。使用 VSCode 或 GNOME Builder 时,在必须手动编译代码之前,这些错误几乎立即出现在编辑器中。这会创建一个非常短的反馈循环,使你可以快速捕获和修复错误。

用纯 Rust 编写 UI

许多 UI 框架都带有自己的 UI 描述语言,允许你指定 UI 布局。最常见的是,它们使用基于 XML 的语法。

我真正喜欢 Relm4 的一个特性是你不需要那样。当然,如果需要,你可以使用 GTK 的 .ui 文件,但你也可以仅使用 Rust 代码来实现 UI。使用relm4-macroscrate,你甚至可以使用非常惯用的语法来编写与结构定义非常相似的 UI。这允许在 UI 和应用程序逻辑之间建立更快、更直接的连接,并在编译器检查所有内容时消除错误。

使用检查器

这个快捷方式是 GTK 的一个非常强大的功能。通过将环境变量 GTK_DEBUG 设置为interactive,GTK 将使用内置检查器打开程序。例如,在 Bash 中,这可以像这样完成:

export GTK_DEBUG=interactive

检查器的工作方式与浏览器中的开发工具非常相似,可让你方便地找出 UI 未按预期工作的原因。你还可以直接修改你的 UI,以找到需要在代码中调整的属性。

GTK inspector in the libadwaita demo application

此外,你可以使用它来分析其他 GTK 程序,尤其是 GTK4 和 libadwaita 演示应用程序。如果你在那里发现了一个有趣的小部件,只需从他们的菜单中打开检查器,然后选择你想了解的更多小部件。这使得为你的应用程序找到合适的小部件变得容易。

使用预建组件

Relm4 的核心可以用 relm4-components crate 进行扩展。它有几个预先构建的组件,可以很好地集成到 Relm4 中,与手动实现相比,可以节省大量时间。

此外,libadwaita[6] 在顶级 GTK4 上提供了许多非常强大的小部件,这为我的 speedrun 节省了大量时间。最好的部分是,Relm4 和 libadwaita 一起工作得非常好。

例子

如果游戏可以选择以预定义的保存状态开始,跳过所有不必要的对话的整个介绍,我怀疑 speedrun 玩家不会使用它。作为开发人员,你也不会从头开始,但如果可用,请使用示例(或来自 Stack Overflow 的代码)。

Relm4 有超过 35 个示例可供选择。你可以将它们用作起点或为某个问题获得灵感。无论如何,他们确实节省了很多时间。

使用 mold 更快地构建

我意识到 Rust 编译器实际上非常快,尤其是对于增量构建。然而,每次我重新编译我的应用程序时,大约需要 8 秒才能完成,因为链接器消耗了大量时间。

使用 mold[7] 我能够将增量编译时间减少 7 倍至仅约 1.2 秒。有了这个,玩 UI 的代码真的很有趣,因为你几乎可以立即看到更改的结果。

After installing mold, all you need to do is add the prefix mold -run to the command you want to run. Most likely this will be

安装 mold 后,你需要做的就是在mold -run要运行的命令中添加前缀。这很可能是:

mold -run cargo run

总结

对我来说,这是一次非常有趣的体验。当然,我这样做主要是为了好玩,而不是为了争执,但我学到了很多东西,我希望你也能从我的经验有所收获。

我认为 Rust 不应该被认为不是 UI 代码的好选择。并非这篇文章中的所有内容都是 Rust 特定的,但我有信心说我比使用任何其他语言更有效率。

我的 speedrun 时间是 1 小时 52 分钟(不过我没有在本文中提到所有功能)。

最终结果

这就是结果的样子:


GIF of the final result

如果你想查看代码,可以在此处[8]找到。要运行它,你可以键入:

cd relm4-examples/libadwaita/
cargo run --example advent_calendar

原文链接:https://aaronerhardt.github.io/blog/posts/gui_speedrun/

参考资料

[1]

Relm4: https://github.com/AaronErhardt/relm4

[2]

想法: https://github.com/AaronErhardt/relm4

[3]

DuckDuckGo 上的图片: https://duckduckgo.com/?q=advent+calendar&t=newext&atb=v236-1&iar=images&iax=images&ia=images

[4]

ViewSwitcherBar: https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/stable/latest/docs/libadwaita/struct.ViewSwitcherBar.html

[5]

StackSidebar: https://gtk-rs.org/gtk4-rs/git/docs/gtk4/struct.StackSidebar.html

[6]

libadwaita: https://gitlab.gnome.org/GNOME/libadwaita

[7]

mold: https://github.com/rui314/mold

[8]

此处: https://github.com/AaronErhardt/relm4/blob/main/relm4-examples/libadwaita/examples/advent_calendar.rs


往期推荐

我是 polarisxu,北大硕士毕业,曾在 360 等知名互联网公司工作,10多年技术研发与架构经验!2012 年接触 Go 语言并创建了 Go 语言中文网!著有《Go语言编程之旅》、开源图书《Go语言标准库》等。

坚持输出技术(包括 Go、Rust 等技术)、职场心得和创业感悟!欢迎关注「polarisxu」一起成长!也欢迎加我微信好友交流:gopherstudio


文章来源: http://mp.weixin.qq.com/s?__biz=MzAxNzY0NDE3NA==&mid=2247489376&idx=1&sn=bff9e3b6a3fba83355973b7b224fa794&chksm=9be33881ac94b1972c50891eede750289f3aefe5f6af2fa36f5decd136f6efe5b364ba7b1a5b#rd
如有侵权请联系:admin#unsafe.sh