本系列教程對應的代碼已開源在 Github zeedle
主要技術選型
UI框架選擇
Slint UI 是一個新興的聲明式GUI框架,使用底層語言Rust編寫,提供Rust/C++/Node/Python使用接口,允許在開發時使用DSL獨立設計UI,樣式與邏輯分離,構建時將UI代碼編譯為機器碼,因此具備極高的運行速度。
相比之下,其他UI框架的缺點(不含基於Web技術的框架,如Dioxus/Tauri):
- egui:即時模式,開發快,適合工具/調試 UI,不適合複雜應用。
- xilem:原來叫druid,實驗性強,生態不成熟。
- freya:類React技術構建UI,依賴Dioxus但是不像Dioxus那樣使用Web渲染器,也是一個很新的庫。
還有一個叫做Iced的框架,也挺流行,據説使用起來會複雜一點,具體情況筆者也不清楚,沒用過。
音頻播放庫選擇
如果不想自己寫底層播放邏輯(如果想,就用cpal與音頻流/設備打交道)或者自行解碼音頻文件(如果想,就用Symphonia解析一切音頻),又想一套函數調用同時處理MP3、FLAC和WAV等格式的音頻,那就有且僅有一個選擇:Rodio。它是由RustAudio直接維護的,看名字就很官方是不是,Rodio本質是基於cpal和Symphonia的封裝庫。
音頻元數據解析庫選擇
音樂播放器需要讀取歌手/歌曲名/歌詞信息/音頻時長/專輯封面/......,並顯示到UI窗口上,這些信息包含在音頻文件的元數據區,如果想用一個庫解析以上所有信息,那麼也幾乎只有一個選擇:Lofty。
架構設計
採用最為經典的雙線程架構以儘量避免UI窗口阻塞卡頓:
- UI主線程:進行窗口渲染,並運行事件循環,持續掃描用户的鼠標/鍵盤輸入,併發送給後台線程處理;
- 後台線程:接收UI主線程發送的任務,處理這些任務併發送UI狀態更新命令給UI主線程。
注意:幾乎所有 GUI 框架(Qt、GTK、Win32、Java Swing、Android、iOS)都讓 UI 線程 = 主線程,這是因為:
- 操作系統事件分發機制要求;
- UI 對象大多不線程安全;
- 事件循環必須唯一且穩定;
- 歷史兼容性;
- 簡化開發模型。