11 月 30 日晚上,我有几个小时的空闲时间,萌生了为 Relm4[1] 编写一个小的 advent(降临节) 日历示例应用程序的想法[2]。因为时间紧迫,我想按计划进行,必须非常快地实施。这让我产生了利用 Rust 进行 GUI 实现加速运行的机会。毕竟,许多人不会认为 Rust 是快速 GUI 开发的好选择。
对于那些不熟悉降临节日历的人:降临节是圣诞节前的这段时间,或者更准确地说是从 12 月 1 日到圣诞节,降临节日历每天都有一扇门。每扇门后面通常都有一个小礼物、一句话或类似的东西。它们在许多国家(至少在德国)很受欢迎,并且通常包含糖果或玩具。见 DuckDuckGo 上的图片[3]。
我发现从 speedrunning 的角度看 GUI 开发非常有趣。它让我更加了解我浪费时间的部分以及我非常快的部分。从我的错误中吸取教训,我认为我可以改进我在未来项目中的策略以及我的生产力。
在开始处理 GUI 应用程序之前,你需要了解 UI 应该是什么样子。你越准确地知道自己想要什么,以后实现 UI 就越容易。
对我来说,查看其他应用程序的布局而不是提出全新的东西可以节省大量时间。在这种情况下,我从 libadwaita “flap” 演示中选择了一个布局,它有一个简单的可扩展侧边栏,允许你选择活动页面,类似于浏览器中的选项卡,但采用垂直布局。
由于我想节省时间,我犯了一个错误,只是选择了听起来像是在做正确事情的小部件。但是,在 Speedrun 的过程中,我意识到我可以使用更好、更简单的小部件。
例如,我尝试使用 ViewSwitcherBar[4] 小部件作为侧边栏的一部分。然而,正如名称和文档所暗示的那样,它只是水平的,并不打算在侧边栏中使用。这导致我多次重构我的 UI 的某些部分,这花费了一些时间,尽管 Relm4 使重构 UI 变得非常容易和快速。
这张图片显示了一个早期版本,它有一个有效的侧边栏,但它看起来不正常,也不能真正识别为侧边栏。如果我之前知道有一个专门用于此目的的 StackSidebar[5] 小部件,我就节省了很多时间。
我从中学到的是花更多的时间来选择最好的小部件。文档始终是一个很好的资源,如果我仔细研究它们,GTK4 和 libadwaita 的演示应用程序也会对我有所帮助。当然,更多的经验也会有很大帮助,并且不出所料,在 speedrun 过程中尝试新事物并没有变得非常快。
快捷键是游戏中几乎所有 speedrun 的重要组成部分。它们可以节省几毫秒到几个小时的时间。GUI 开发也是如此。了解正确的工具可以跳过通常需要更多时间才能完成的部分,从而显着加快你的工作流程。
使用 Rust 的一个好处是我经常认为理所当然的类型系统和所有权规则,可以在编译时防止很多错误。使用 VSCode 或 GNOME Builder 时,在必须手动编译代码之前,这些错误几乎立即出现在编辑器中。这会创建一个非常短的反馈循环,使你可以快速捕获和修复错误。
许多 UI 框架都带有自己的 UI 描述语言,允许你指定 UI 布局。最常见的是,它们使用基于 XML 的语法。
我真正喜欢 Relm4 的一个特性是你不需要那样。当然,如果需要,你可以使用 GTK 的 .ui 文件,但你也可以仅使用 Rust 代码来实现 UI。使用relm4-macros
crate,你甚至可以使用非常惯用的语法来编写与结构定义非常相似的 UI。这允许在 UI 和应用程序逻辑之间建立更快、更直接的连接,并在编译器检查所有内容时消除错误。
这个快捷方式是 GTK 的一个非常强大的功能。通过将环境变量 GTK_DEBUG
设置为interactive
,GTK 将使用内置检查器打开程序。例如,在 Bash 中,这可以像这样完成:
export GTK_DEBUG=interactive
检查器的工作方式与浏览器中的开发工具非常相似,可让你方便地找出 UI 未按预期工作的原因。你还可以直接修改你的 UI,以找到需要在代码中调整的属性。
此外,你可以使用它来分析其他 GTK 程序,尤其是 GTK4 和 libadwaita 演示应用程序。如果你在那里发现了一个有趣的小部件,只需从他们的菜单中打开检查器,然后选择你想了解的更多小部件。这使得为你的应用程序找到合适的小部件变得容易。
Relm4 的核心可以用 relm4-components
crate 进行扩展。它有几个预先构建的组件,可以很好地集成到 Relm4 中,与手动实现相比,可以节省大量时间。
此外,libadwaita[6] 在顶级 GTK4 上提供了许多非常强大的小部件,这为我的 speedrun 节省了大量时间。最好的部分是,Relm4 和 libadwaita 一起工作得非常好。
如果游戏可以选择以预定义的保存状态开始,跳过所有不必要的对话的整个介绍,我怀疑 speedrun 玩家不会使用它。作为开发人员,你也不会从头开始,但如果可用,请使用示例(或来自 Stack Overflow 的代码)。
Relm4 有超过 35 个示例可供选择。你可以将它们用作起点或为某个问题获得灵感。无论如何,他们确实节省了很多时间。
我意识到 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 分钟(不过我没有在本文中提到所有功能)。
这就是结果的样子:
如果你想查看代码,可以在此处[8]找到。要运行它,你可以键入:
cd relm4-examples/libadwaita/
cargo run --example advent_calendar
原文链接:https://aaronerhardt.github.io/blog/posts/gui_speedrun/
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