C++ 是否適合做 GUI?

為什麼 C++ 做 GUI 就那麼難呢? C# 學了倆月我同學已經像模像樣的作出一些小程序了,我學了快一年了還只是命令行界面混。


C++ 過於靜態的固有缺點有答案已經說了。從 runtime 角度來說,C++ 的 UI 方案和 C#, Objective-C 之類也不在一個層次上。

C#, Objective-C 的 UI 方案是自己提供 toolkit。它們面對的底層是一個 render model。這個 model 負責 Bézier curve, blending, crop, mask 等等機制。這些機制只有組合而沒有擴展關係。C#, Objective-C 在這個 model 之上建立一個 toolkit framework,有基本的 view,也有 button 這樣的 control,這個 framework 既提供組合也提供擴展。

理論上說,C++ 也可以實現這個東西。用 OpenGL, DirectDraw 之類的東西實現一套 framework。其實 WPF 也就是 C++ 這麼實現的,但是最後沒有 expose C++ interface。所以實際上,C++ 失去了建立這個 framework 的機會。現在的 C++ UI 都是封裝其它的 toolkit framework。如果說 C++ 比較接近 C#, Objective-C 的模式也只有 Linux 下的 Qt。在其它平台上,在一個可以擴展的 framework 上再封裝另一個可以擴展的 framework,最後的結果就是學習曲線和抽象泄漏都很高。

有答案說很多 app 都是用 C++ 寫的。老一些的 app 是這樣。但是新的 app 很少干用 C++ 封裝其它 toolkit 的事情了,連現成的 Qt 用起來都覺得缺乏控制。新的 app 更傾向於把 model 和 view 區分開,用 C++ 寫 model。C++ 的另一個用途是,如果 app 里有比較複雜的 custom view,C++ 可以直接用 render model 實現這個 custom view。但是整個 UI presentation layer 都用 C++ 寫的 app 並不是占絕對多數。即使是多平台 app 也是如此。

@vczh 提到了他的 GacUI。這種 OS vendor 之外的第三方在 render model 之上開發的 toolkit framework 要面對很多超出開發者能力之外的問題。UI 本身的 style 要不斷追逐 OS 的變化。而且在處理 localization,text layout,user gesture 的時候,都要面臨是自己重新開發還是直接利用 OS 的現有機制的兩難決定。所以說第三方並不能解決 C++ UI 的困境。UI framework 是一個被 OS vendor 壟斷的領域,如果沒有 OS vendor 把 C++ 作為 UI 的第一語言(像 Qt for KDE 那樣)就不能解決 C++ 開發 UI 困難的問題。


做過10年C++ GUI的人飄過。題主的感覺並沒有錯,C++「本身」並不太適合寫GUI。

因為C++本身不具備反射和自省,類體系結構非常的靜態,且抽象能力有限。但GUI是個相當動態的東西,所以最「基礎」的C++並不適合寫GUI,硬寫的話最後的程序會非常的verbose。

聰明的GUI庫通常會用一些技巧繞過這個問題:

1. 大量宏技巧來保存meta信息。如MFC、wxWigdet。

2. 用額外的source transformer來提供反射和動態messaging能力,如Qt。

3. 在C++基礎上實現一個Domain Specific Language。包括Qt,以及各種DirectUI方案。

嚴格意義上講,後兩種手段是統一的,都屬於DSL方法,所以已經不能算是純粹的C++。

最適合寫native GUI的語言是Objective-C,即便拋棄Cocoa庫來講,單純的論語言能力也是如此。可惜的是不跨平台。

如果不追求native,那麼最適合的是HTML/CSS/JS(允許hybrid方案的話可以在C++中嵌入webkit,但需要注意C++和JS之間的通信不是那麼的方便),理論上來講它是把結構描述(HTML)、樣式描述(CSS)和動態計算(JS)劃分的最好的,且高度標準化。如果你的GUI程序中不存在高性能實時渲染的話(如毫秒級更新的圖表、或嵌入OpenGL/D3D窗口),那麼配合angularjs之類現代的client MVC庫,手感和響應完全可以達到和native程序一樣,且寫起來比C++輕鬆和簡潔很多。javascript本身是個不怎麼樣的語言,但這不妨礙HTML/CSS/JS組合在一起的能力。事實上很多人自己輪過的DirectUI方案都只是這個方案的子集的「拙劣」模仿,包括Qt的stylesheet、QtScript。

至於為什麼這麼多流行的GUI庫都用C++實現,很多原因不是在語言本身的能力上,幾個可能的原因是:

1. GUI是個基礎構件,用C/C++這種較基礎和非常流行的語言來實現的話,可以讓這個庫被更多的其它語言所使用。

2. native。很多需求不允許C#這種帶一個厚厚運行時的東西,或者帶一個肥碩的Webkit。尤其對互聯網客戶端來講,需要發布的東西越小、越輕量,越好,所以這些公司的客戶端基本上都是自己輪一個輕量級的DirectUI,只滿足自己的需求即可。

3. 保留了在性能和抽象之間做權衡的能力。如果採用了HTML/CSS/JS,那麼當你需要高性能實時渲染時,可能無法實現。做為一個庫來講的話,用戶的應用場景千變萬化,必須要為這些可能性保留相關的能力。

總得來說用C++寫GUI需要付出更多的努力,但回報也更高,前提是有一個或輪一個靠譜的DSL。事實上HTML/CSS/JS也可以看作是一個DSL,運行在C++寫成的解釋器(瀏覽器)上。


偵測到在途vczh。

題主去隔壁C#看到人家寫出來的程序Aero風格的毛玻璃,Metro風格的小瓷磚

而且人家只用了兩個月呢,太羨慕啦,自己寫了一年C++還在寫「press any key to continue...」呢

瞬間感覺被人家碾壓了,C++就逆襲不了么?人家走「優雅」風,你來走「酷炫」風!

長啥樣子的程序比較酷炫呢?是激活碼生成器!怎麼可能?當然是遊戲!!!

看看別人家做遊戲用啥做的GUI,造輪子已經來不及了,快使用開源軟體,哼哼哈嘿!

////////////下面推銷CEGUI給題主用////////////

CEGUI是久經考驗的GUI庫,項目年齡超過十年

被應用在很多流行的遊戲中,國內有這個《天龍八部》,國外的有這個《火炬之光》

它能做到什麼樣大概了解了吧,再貼一個酷炫的官網例子,觀看此視頻需要翻越長城

https://www.youtube.com/watch?v=iXsZh1owpBI

  • CEGUI沒有MFC那種大量的宏技巧,也沒有DSL,完全面向對象設計,使用過程還能順便學習一下設計模式

  • 跨平台設計,支持Windows Linux MacOS
  • 支持Unicode,額,中文
  • 使用XML做數據驅動控制,有官方編輯器CEED,所見即所得的編輯布局,管理圖片集
  • 控制項十分豐富,基本你想用的都有,不夠也可以自己擴展
  • XML解析器可選expat xerces tinyxml rapidxml libxml等
  • 圖片解碼器可選tga silly devil freeimage stb corona等
  • renderer有OpenGL 2.X OpenGL 3.2+ Direct3D 9 10 11 Ogre3D Irrlicht等
  • 感覺C++不爽了可使用腳本語言,python和lua
  • 還有外觀系統換皮膚,可以找到很多酷炫的皮膚用,逆襲就靠它了
  • 還可以使用特效,什麼WindowEffect RenderEffect簡直無情

有豐富詳實的在線文檔,SDK里還有直接能跑起來的例子,很容易學,找個例子改一改就是一個題主你講的「像模像樣」的程序!

////////////別的樓開始聊最好的GUI語言////////////

顯然是ActionScript,這個自省反射全都有,語言還內建事件機制,簡直是為GUI而生。

作為一名CPP大法習練者,ObjC代碼長得太怪,JavaScript槽點太多

ActionScript我還是可以接受的,成功的應用也不少:

《星際爭霸2》用的Scaleform,《英雄聯盟》用的Flex,還有數不清的頁面應用。

Flex的MXML/ActionScript/CSS我總感覺是青出於藍而勝於藍,不僅數據結構清晰,更釐清了程序員/交互設計師/藝術家的工作。

題主,才開始了一年C++可不能放棄,CPP大法好!


GUI 的核心繪製方法比較適合使用 C/C++ 來製作。而GUI 的具體控制項製作則非常適合使用腳本語言構建。

而GUI的具體業務邏輯部分由於和需求聯繫緊密,變動比較頻繁,也是比較適合使用腳本語言以及使用弱類型的語言來處理。

核心繪製包括了Dirty檢測,效果演算法(border, shadow,shader等) 以及 排版處理 (Layout)。這塊內容是特別需要和GPU打交道,以及和效率打交道的地方。是 c/c++ 擅長的領域。

事件派送,動畫混合以及變數變動檢測部分也同樣需要放在核心層處理,讓腳本語言來響應事件定義出控制項。這樣做的好處是,你可以很容易地作出非常多的控制項,而底層 c/c++ 永遠只關心最核心的事件處理需求。

=================

題外話:其實我覺得題主如果去遊戲領域做GUI的話,就會有滿滿的成就感以及無窮無盡的追求。我個人覺得遊戲領域的GUI真是個好課題,當然我說的是要能夠融入到3D環境中的GUI。這方面不僅需要我們傳統的GUI知識,還需要很多在3D交互中對GUI控制項的表現追求。真的是一個好坑!也是C/C++做GUI最有成就的地方之一。

此外,研究 html 領域中 css 對 div 的繪製定義,排版定義和 transition 並將他們用 c/c++實現也能給你帶來滿滿的成就感。

我覺得從這些方面入手c/c++ GUI 的書寫會是個不錯的入口。題主加油!


世界上用戶量最大的幾十個GUI程序大多數都是C++寫的,還有比C++更適合寫GUI的嗎?

單純看語言特性來談是否適合開發GUI是片面的,GUI程序的特點就是代碼規模都比較大,這就涉及一個工程上的可行性問題。

在工程角度看,語言特性只是一方面,還有很重要的幾點,

一是工具鏈是否完善,不僅是編譯工具,還有調試,測試,性能優化診斷,靜態代碼檢查,崩潰分析,內存泄漏檢測優化,工程管理,集成開發環境等等

二是運行庫是否豐富,開發中需要的各種框架庫,演算法庫,服務介面封裝庫等等。

三是文檔和知識庫是否豐富

C++相比其他語言在這幾方面的積累相當深厚,主要是出來早,功能多,在很早期就領先其他語言一大截,經過幾十年這種優勢依然巨大,而且還在緩慢拉大。

目前來看,C++真的就是最適合開發GUI的語言

在語言特性上來看 Objective-C更優秀,但是這種優勢僅限於MacOS和iOS平台,離開的Apple生態圈OC就是廢物了。

Java和C#現在也各自有了自己的優勢平台(Android,WinPhone),在主場作戰是能勝過C++的,我相信有一天當PC消亡了,C++將失去在GUI開發的領先地位。

從題主的描述看,他說的是PC平台,答案是肯定的,C++還是最好的,但不是唯一好的。


首先,C++最重要的應用是大型底層設施,比如資料庫引擎、物理引擎、圖形引擎。

然後:Qt,Gtk,Wxwidgets,MFC……你自己知道的太少而已。

最後,你那同學用C#調的東西,也八成是C/C++弄的庫。


CreateWindow function (Windows)

如果你是Windows用戶,那麼就從這裡開始慢慢看吧

不過預先警告:Win32和其他平台相比是另一個次元 你必須適應完全不同的一堆概念


1.C++很適合寫界面,只要有人給你造輪子,可以寫的非常爽

2.能寫界面的語言太多了,基本上常見的語言都有GUI庫,所謂適不適合只是GUI框架的封裝好不好用吧。語言特性本身倒是次要的

3.私以為,最適合寫界面的還是XML(html),這種語言天生就是用來描述界面的。你看不管是安卓、iOS還是WPF,都把大量繁重的布局描述工作交給了XML來描述,再用其他語言來實現邏輯部分。更何況跟html一比,任何編譯型語言寫起界面來都弱爆了

4.為什麼我每次回答問題都跑題呢-_-#


和當前很多非原生的程序界面開發,以及基於Web腳本的界面開發相比,C++開發界面沒有什麼優勢。


你是為了造 Webkit 這樣的東西用 C++ 還差不多. 如果為了 new Button, onClick show boob 還是別折騰了吧. 浪費精力.


C++並不適合寫界面邏輯,任何編程語言都不如標記語言適合寫gui。C++適合寫引擎,然而引擎又不需要我們自己寫。

如果主體部分是拿C++寫的,而且不能重構的時候,我們可以拿html寫界面,然後c++調用webkit來渲染。就是這樣。


我就用C++造了個輪子,至今已經造了7年多,還沒有終止,也不打算終止.

這裡應該有人知道,叫炫彩界面庫;

肯定的告訴你C++可以做GUI;

一種是開發GUI框架給別人用,比如我, 另一種是找到一個別人造好的輪子用.

有好用的輪子就不難, 人就是善於使用工具.

如果你不開發GUI框架,那就找個輪子用.拖拖拽拽就完成大部分UI工作.

上傳一個UI設計器截圖你看,C++做UI不難, 難的是找到好用的工具.


我自學過qt ,感覺可以滿足題主的這方面的需求(工作中用處不大)


qt我覺得還挺好的


很多人回答的是「c++【能】做gui」,沒錯,但沒切題:【適合】做gui嗎?

就方便來說,vb、pb、delphi/c++builder都比較【方便】做gui

但是,如果需要一些特殊的界面,如果c/c++是很自然用api實現(普通的界面,它本來也都是這樣實現的,雖然不方便,但肯定【能】)

而delphi也較方便用api實現這些特殊的地方

(vb/pb估計也是【能】的,但方便性就沒了)

所以:較合理、合適的組合是

gui用delphi,底層是c/c++生成的命令行程序,交互是:

輸入:ini格式的命令行capp.exe a=1 b=2 c=3 ...

輸出:標準輸出

delphi網路、資料庫都方便,開發高效,用戶使用的便捷

c/c++操作底層方便、現成代碼多

當然,這基於:win32桌面的gui

要跨平台,還是c/c++,麻煩就麻煩了;或者java,慢就慢了

c#比較接近delphi了,但 運行速度還是略慢了一點(sql2000和sql2005管理器的速度差異)


We are still winning, but we are losing the war.


快用 VC++ 6.0 的 MFC 吧少年!哈哈哈哈哈!(淫笑)


控制台程序→win32應用程序?

你可以去看《windows程序設計》。這本書有點老,看到你找到你需要的東西既可。


就gui本身來說,不合適,很不方便。而現實中,之所以那麼多用c++寫的gui因為沒辦法,因為除了界面以外還有其他因素影響你的選擇。比如,要求應用程序體積最小,沒有外部依賴,你總不能先裝一個.net或java…


推薦閱讀:

為什麼 C 語言的輸入輸出函數比 C++ 的輸入輸出流要快?
有沒有比較好的自學IT的網站?適用於不管是初學者還是其他段位的程序猿的網站?
如何評價2016年藍橋杯決賽?

TAG:編程語言 | 編程 | CC |