我的 Rust GUI 開發之旅

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

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/uiqjB1aq6u2QJ1gjDb0hxg