Windows 下的 GUI 開發(fā),真的太難了!多種方法開發(fā) GUI
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
近日,開發(fā)者 Samuel Tulach 在個人博客上感嘆道,“在 Windows 上編寫 GUI 應(yīng)用程序真是太難了!”在文中, Samuel Tulach 討論了使用 C++ 編寫 GUI 應(yīng)用的各種困難。他詳細(xì)列舉了幾種流行的庫,但這些庫通常會面臨諸如依賴項管理、應(yīng)用程序大小以及樣式定制等問題,并沒有完全契合的解決方案。 萬萬沒想到,這個小吐槽引起了不少開發(fā)者的共鳴,甚至登上了 HN 熱榜。接下來,我們將通過本文看看難點究竟在哪里? 過去幾天里,來自捷克的程序員 Samuel Tulach,一直在尋找一個能夠讓他用 C++ 編寫帶有 GUI 程序的庫。他給出的要求非常簡單:
所以,Samuel Tulach 開始挑選一些稱手的工具、框架,結(jié)果發(fā)現(xiàn)并沒有想象中那么簡單。
WinUI 3 首先,Samuel Tulach 從專為 Windows 應(yīng)用程序開發(fā)而設(shè)計的現(xiàn)代化的用戶界面(UI)框架——WinUI 3 入手。 乍一看,它是個不錯的選擇。它允許你使用現(xiàn)代的 Windows 組件,還可以自定義樣式顏色。設(shè)計方面,你可以使用非常容易掌握的 XAML,或者直接使用 Visual Studio 設(shè)計器。 WinUI 3 控件庫 問題:使用 WinUI 3 框架開發(fā)的應(yīng)用程序在發(fā)布時不能以無包裝(unpacked)的形式進(jìn)行分發(fā)。這意味著無法將應(yīng)用程序打包為一個單獨的可執(zhí)行文件(.exe)及其所需的所有依賴項,而是需要依賴于特定的分發(fā)方式,如打包為 AppX 包或者通過 Microsoft Store 進(jìn)行分發(fā)。 對于 Samuel Tulach 而言,大多數(shù)情況下,當(dāng)他嘗試將應(yīng)用程序遷移到虛擬機(jī)或不同計算機(jī)時,由于缺少一些不明依賴項而無法正常啟動。更糟糕的是,你需要提供一堆處理 WinUI 功能的 .dll 文件,沒有辦法提供一個可移植的 .exe 文件。使用打包形式通常沒有問題,但它們是以 AppX 包的形式安裝的,這本身就會帶來很多問題(尤其是在需要訪問所有 Win32 API 的情況下)。
Win32 / MFC / 封裝 Win32 的小型庫 緊接著,Samuel Tulach 將目光轉(zhuǎn)移到了 Win32 身上。Win32 是一種應(yīng)用程序編程接口(API),它是微軟 Windows 操作系統(tǒng)的核心組成部分。它提供了開發(fā)者與操作系統(tǒng)交互的一組標(biāo)準(zhǔn)接口和功能,用于創(chuàng)建和管理 Windows 應(yīng)用程序的各個方面,包括窗口、消息處理、文件操作、網(wǎng)絡(luò)通信等。 Samuel Tulach 表示,其需要高度的可移植性,因此使用操作系統(tǒng)的原生渲染是有道理的。這樣的程序可以是一個單一的 .exe 文件(因為我們對 MFC 進(jìn)行了靜態(tài)鏈接),而且體積超?。ㄖ挥袔浊ё止?jié))。 同時,Samuel Tulach 稱,還可以使用別人已經(jīng)編寫好的更簡約的庫,這意味著從概念到可運行應(yīng)用程序的快速實現(xiàn)將變得非常容易。 基本 Win32 形式 問題:對原生的 Win32 控件進(jìn)行樣式化處理是一項非常困難的任務(wù)。為了改變這些空間的外觀和風(fēng)格,Samuel Tulach 需要為每一個控件編寫一個專門的自定義繪制函數(shù),這個過程不僅需要詳細(xì)了解 Win32 API 的繪制機(jī)制,還需要大量的時間和精力投入。 對此,Samuel Tulach 吐槽稱,“有這個時間,我都可以直接去養(yǎng)家糊口了。” 此外,Windows 文件資源管理器(File Explorer)使用的一些原生 Win32 控件具有一個被稱為 “隱藏” 的暗色模式。用戶可以激活這個模式,但它只會對部分控件生效,并且在視覺效果上并不十分理想或完善。
Qt Qt 在 C++ 圖形用戶界面開發(fā)中被認(rèn)為是一個非常優(yōu)秀的選擇。盡管它相對復(fù)雜,但它提供了 Qt 樣式表(Qt Style Sheets),這使得開發(fā)者可以輕松地設(shè)計和定制界面的外觀和樣式。Qt 樣式表使用一種類似于 CSS 的語言,讓開發(fā)者可以用熟悉的方式來定義控件的外觀、布局和交互效果。 OBS studio 使用 Qt 和自定義樣式表 然而,問題在于,當(dāng)使用動態(tài)鏈接方式時,運行 Qt 應(yīng)用程序需要大量不同的 .dll 文件,這些文件總共的大小超過了 40MB。為了減少文件大小,可以選擇將 Qt 靜態(tài)鏈接到應(yīng)用程序中,這樣未使用的部分會被移除,從而減小應(yīng)用程序的體積。 不過,Qt 使用的是 LGPL 許可證。根據(jù) LGPL 的條款,如果選擇靜態(tài)鏈接 Qt,那么必須遵守 LGPL 的要求之一:要么開源應(yīng)用程序的源代碼,要么提供用于重新編譯的目標(biāo)文件。另外,Qt 也提供了商業(yè)許可證選項,可以以幾千美元的價格購買,從而免除遵守 LGPL 條款的義務(wù),只是這樣成本又太高了。
wxWidgets wxWidgets(https://www.wxwidgets.org/)是一個相對容易學(xué)習(xí)的庫,還可以使用 wxFormBuilder。它所遵循的許可證要比 Qt 更寬松,可以靜態(tài)鏈接成一個 3MB 的可執(zhí)行文件。 wxWidgets 啟用了實驗性的 Windows 暗模式選項 問題:wxWidgets 是一個在 Windows 上使用原生的 Win32 組件的庫。然而,與直接使用 Win32 或 MFC 相比,wxWidgets 并沒有提供輕松覆蓋繪制函數(shù)的選項,因此在樣式定制方面甚至比直接使用 Win32 或 MFC 更為困難。 盡管 wxWidgets 支持應(yīng)用 Windows 文件資源管理器的暗模式控件,但實際效果并不理想。
hikogui hikogui(https://github.com/hikogui/hikogui)是一個相對較新的保留模式 GUI 庫,它使用 Vulkan 作為后端技術(shù)。這意味著它利用 Vulkan 的強(qiáng)大功能來進(jìn)行圖形渲染和顯示。hikogui 內(nèi)置了暗模式的支持,開發(fā)者可以很容易地自行定制和樣式化界面,以適應(yīng)應(yīng)用程序的需求和設(shè)計風(fēng)格。 問題:要成功編譯 hikogui,可能需要具備計算機(jī)科學(xué)博士學(xué)位,特別是在編譯器開發(fā)方面的專業(yè)知識。在體驗過程中,Samuel Tulach 嘗試了超過 30 分鐘去編譯示例,包括嘗試不同的代碼分支和發(fā)布標(biāo)簽,但最終只得到了一個立即在某個 Vulkan 庫內(nèi)發(fā)生訪問沖突的可執(zhí)行文件,因此他決定放棄嘗試。 不過,盡管 Samuel Tulach 不太喜歡大量使用 STL(標(biāo)準(zhǔn)模板庫),甚至認(rèn)為有時候并不是必需的,但他認(rèn)為 hikogui 看起來確實有前景。
Sciter Sciter 實際上是一個不錯的 Electron 替代品,允許開發(fā)者使用 HTML/CSS 編寫桌面應(yīng)用程序的 GUI。 SVG 圖標(biāo)上抗鋸齒效果不佳的示例 問題:你可能認(rèn)為應(yīng)用程序大小或稱為一個問題,但實際上,包含所有必需的 .dll 文件的最終應(yīng)用程序大小大約只有 25MB,這對 Samuel Tulach 來說完全可以接受。 Samuel Tulach 表示,如果 Sciter 能夠完全開源,那將是更好的選擇,因為這樣開發(fā)者可以將靜態(tài)鏈接版本用于商業(yè)用途(與 Qt 的問題相同)。同時,Sciter 的獨立許可證價格相比 Qt 要低不少(目前為 310 美元),Samuel Tulach 也愿意為此支付費用。 然而,現(xiàn)在不選用這個框架的主要原因在于,如上圖所示(看看標(biāo)題欄圖標(biāo)),渲染效果不太好。在體驗過程中,Samuel Tulach 透露其遇到了各種字體和圖像的抗鋸齒問題(啟用了高分辨率選項,即使在預(yù)編譯的 scapp.exe 中也存在這個問題)。而且,無論你做什么,窗口都會有一個相當(dāng)厚(2-3 像素)的灰色邊框,完全無法自定義或修改。 WinForms / WPF 如果你在一些論壇上詢問關(guān)于在 Windows 上使用 C++ 編寫 GUI 庫的問題,大概率會收到一些“這不是一個好主意”等類似的反饋,甚至論壇上的專家們會直接建議你采用其他技術(shù)堆棧來編寫應(yīng)用程序的前端部分,然后將用 C++ 編寫的功能作為組件或模塊加載進(jìn)來。 這種做法可以讓你更輕松地定制和風(fēng)格化界面,并顯著加快開發(fā)速度。從技術(shù)角度來看,確實可以使用像 WinForms 或 WPF 這樣的工具生成一個體積較小的單獨可執(zhí)行文件(.exe)。 詳細(xì)來看,有兩種方式可以實現(xiàn):
問題:.NET Framework 在 Windows 10 及更新版本中是預(yù)裝的,因此從技術(shù)上來說,我們?nèi)匀豢梢詽M足無依賴項的標(biāo)準(zhǔn)。然而,如果我們選擇將 C++ 編寫的功能模塊打包為 .dll 文件,我們?nèi)匀恍枰谶\行時將這些 .dll 文件從打包的資源中提取到一個臨時位置,并編寫額外的 P/Invoke 代碼來調(diào)用這些模塊。 此外,如果使用 C++/CLI 編譯,生成的代碼將轉(zhuǎn)換為 .NET IL 代碼。換句話說,生成的應(yīng)用程序可以在調(diào)試工具(如 dnSpy)中打開,你可以看到 C++ 代碼被翻譯為等效的 C# 代碼。這種情況下,生成的應(yīng)用程序并不是純粹的原生代碼應(yīng)用程序,而是包含了.NET Framework 的中間代碼。 而正如文章伊始所提及的,Samuel Tulach 想要原生的代碼,所以基于 WinForms 或 WPF 得到的代碼并不他真正想要的。
解決方案? 以上是 Samuel Tulach 考慮過的幾個方案。經(jīng)過長時間嘗試各種不同的庫,甚至一度編寫自己的 MFC 樣式之后,Samuel Tulach 發(fā)現(xiàn)對于簡單的應(yīng)用程序來說,沒有什么比 Dear ImGui 更合適的了。 Dear ImGui 是一個用于 C++ 的輕量級界面開發(fā)框架,它的主要目標(biāo)是提供高效、靈活和易于使用的界面開發(fā)工具。Dear ImGui 是一個基于文本的界面開發(fā)框架,它使用簡單的文本命令來創(chuàng)建和更新用戶界面。 不過,Dear ImGui 在設(shè)計復(fù)雜的用戶界面時也有一些缺點,而且它不是保留模式的用戶界面,而是即時模式的用戶界面,因此想要使用,必須運行像 DirectX 這樣的 GPU 渲染器來渲染每秒 60 幀或更多幀的用戶界面。 正如上圖所示,Samuel Tulach 已經(jīng)寫了一個示例,如何使用內(nèi)置的多視口功能來制作簡單的圖形用戶界面應(yīng)用程序。 編譯后的程序大小只有500KB,非常小巧。這個程序不需要安裝任何額外的依賴項,即使是將 MFC(Microsoft Foundation Classes)靜態(tài)鏈接到程序中,也不需要安裝 VC++(Visual C++)的運行時庫。這使得部署和使用這個程序變得非常簡便,用戶可以直接執(zhí)行這個程序而無需擔(dān)心缺少運行時組件或依賴項。 對于 Samuel Tulach 這段經(jīng)歷,不少開發(fā)者感同身受。來自 HN 的網(wǎng)友 pshirshov 表示: 我也有過類似痛苦的經(jīng)歷。我需要一個真正跨平臺(Windows、Linux/Wayland、Mac、iOS、Android)的 GUI 工具包,它要有豐富的控件庫和合理的主題。事實上,唯一不錯的選擇是 QT,而使用 C++ 很難提高效率,因為它仍然缺乏基本功能,如類型解構(gòu)和帶窮舉檢查的 ADT/GADT。QT 與其他語言的綁定還不夠成熟。 除了 QT 之外,還有漏洞百出的 Avalonia。對 Linux 的支持非常糟糕。 此外還有 Kotlin/Compose Multiplatform。它缺乏良好的文檔和先進(jìn)的控件,而且仍然充滿 Bug。 我無法找到任何適用于 JS/TS 的優(yōu)秀控件庫,即使是付費的控件庫(如 Telerik 和其他控件庫)也非常混亂。因此,Electron、Capacitor、React Native——它們都認(rèn)為即使是一個非常基本的應(yīng)用程序也需要投入大量精力。 Flutter 給人的感覺極不成熟,尤其是全局單例模式的普及使得在使用 Flutter 時,即使是管理小型代碼庫也變得非常困難。 另一用戶稱: 在 Mac 上我遇到同樣的困擾,我在 Mac 上 SwiftUI 的體驗是,它仍需要大量工作。文檔很差。如果你以直截了當(dāng)?shù)姆绞阶鍪?,性能可能會很差。支持舊版本的操作系統(tǒng)相當(dāng)痛苦等等。 至此,你是否體驗過 GUI 開發(fā)?有哪些工具推薦? 來源: https://news.ycombinator.com/item?id=40839208 https://tulach.cc/writing-gui-apps-for-windows-is-painful/ 該文章在 2024/7/8 15:22:48 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |