日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

MFC和QT等UI框架的特点

發布時間:2023/12/18 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC和QT等UI框架的特点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

UI設計的3大原則:

  • 面向對象;
  • MVC;
  • 消息隊列驅動;

直到現在各個UI系統,包括題主所提到的MFC、WPF、Qt,也包括其它,諸如Android SDK、Cocoa的構建仍舊建立在這3大原則的基礎上。

要提到MFC,就不得不先提到Windows SDK,后者是隨Windows 1.0所提供的操作系統API。Windows 1.0在1985年發售,盡管在此之前已有施樂的Star、蘋果的Lisa和Mac OS這樣的圖形界面操作系統,但Windows 1.0畢竟是第一個大規模發行的圖形操作系統,需要直面各樣的開發者與普通用戶的問題,也算是“第一個吃螃蟹的”。既然是第一個,當然是不成熟的。這種不成熟即有當時技術條件的限制,也有經驗上的匱乏,我用一個例子簡要說明一下。例如,我需要顯示一個窗口,Windows SDK看上去是這樣的:

int WinMain() {//1 register a window classWNDCLASS wndclass;wndclass.style = CS_HREDRAW | CS_VREDRAW;wndclass.lpfnWndProc = WndProc;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = NULL;wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.lpszMenuName = NULL;wndclass.lpszClassName = "MainWndClass";RegisterClass(&wndclass);//2 create a winowHWND hwnd = CreateWindow("MainWndClass","Window Title",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);//3 message loopMSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}return 0; }

對,你沒有看錯,那個叫CreateWindow的函數的有11個參數!按照面向對象的觀念與簡潔性的做法,它不應該是這樣的嗎(一個Gtk的例子):

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_title(window, "window title"); gtk_window_set_position(window, GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_default_size(window, 400, 300); gtk_window_set_resizable(window, TRUE);

原因是當時的機器內存太小,一個函數的鏈接符號要占有一個字長的地址空間,所以能省就省。這也是當時諸多系統API設計的慣例,如之后蘋果的Carbon庫,參數多到慘不忍睹的函數也是比比皆是。這就是所謂的“技術限制”的一例。

此外,上例中第一步“注冊窗口類”和第三步“消息循環”有必要強制要求用戶來指明各個參數項嗎。從后來的實踐看,答案是沒有必要。但作為“第一個吃螃蟹的”,怎么會知道。這就是所謂的“經驗上的匱乏”一例。

作為后起之秀的Qt,同樣是顯示一個窗口,用戶代碼就簡潔得多:

int main(int argc, char *argv[]){//1 create application instanceQApplication app(argc, argv);//2 create a windowQWidget *window = new QWidget;window->setWindowTitle("title");window->show();//3 message loopreturn app.exec(); }

正由于Windows SDK的不如意,于是就出現的MFC。

這里我想插一個題外話:為什么用戶終端系統(包括Windows、mac OS這樣的PC端,Android、iOS這樣的移動平臺,也包括Play Station、xbox這樣的家用主機),所提供的的API和程序庫接口,編程語言都是類C(C、C++、ObjC、Java等)的。這主要是技術積累的緣故。早期探索用戶終端系統的開拓者,使用的C語言,先驅們在這一語言基礎上構建起各種基礎設施,包括教育環境與人才儲備,項目管理的流程與經驗,開發、分析、測試工具,建議做法與禁忌。作為后來者當然不會舍棄這些基礎設施而另起爐灶從零開始,于是使用類C語言就成了傳統。可以預見:下一代的用戶終端與的程序庫接口,也是類C的編程語言。

我們回到MFC的話題。MFC只是對Windows SDK的封裝,按后世的看法,MFC不按“套路”出牌!包括作為同時代競爭產品的Borland公司的VCL,還有稍晚的Java awt,也是不按“套路”出招!這里我需要解釋下圖形庫構建的“套路”是什么,讀者才能理解什么叫“不走套路”。

對于一個圖形界面的程序,大致可以分為3個層:

+----------------------+ | user application | +----------------------+ | ui framework | +----------------------+ | operation system api | +----------------------+

最下面的是操作系統API,無論是UI庫還是用戶程序,要實現某功能最終都是要依賴于操作系統API的。關鍵點在于,操作系統需要提供多少數量的API函數,才足以構建一個圖形界面程序。答案是:很少。

首先,操作系統需要為UI框架和用戶程序提供一塊屏幕區域:

struct window *window_create();

其次,這塊區域需要能夠接收用戶事件(這里以鼠標點擊為例):

enum mouse_event {mouse_event_down,mouse_event_move,mouse_event_up };typedef void (*mouse_handler)(struct window *, mouse_event event, int x, int y);void window_set_mouse_handler(struct window *, mouse_handler handler);

最后,UI框架與用戶程序需要在這塊區域繪制各種控件(下例是矩形):

struct context *context_get_form_window(struct window *);void context_set_color(struct context *, int rgba); void context_fill_rect(struct context *, int x, int y, int width, int height);

只要有了這3類API,一個圖形界面程序就可以構建出來了,即使如今復雜的3D圖像程序也是如此。這些作為基礎API的函數數量很少,往大的說不到一百個,往小的說,十多個也能成事。龐大的UI框架,諸如Qt、Xamarin、WinForm,僅僅是以這幾十個操作系統API函數作為自己的基礎;對操作系統極小的依賴,也是可移植的保障;也是UI框架構建的“套路”。

所以說微軟的MFC、Borland的VCL不走“套路”,因為它們都是對Windows SDK的封裝,而不是選擇少量Windows SDK核心函數并在其上構建自己的工作邏輯。因為Windows SDK使用繁瑣,于是有了MFC,但MFC是對Windows SDK的直接封裝,雖然提升了易用性,但終究要沿用Windows SDK所定義的工作流程。當然這種做法也是有好處的,例如工作量更小、用戶可以更方便地直接調用系統API。

說穿了,MFC(當然也包括VCL)需要解決的是“有無”的問題。Windows 1.0這樣的圖形界面操作系統已經開始在大眾領域普及,開發者也需要一套框架來開發圖形界面程序。MFC在上世紀90年代取得了巨大的商業成功,但以后世程序員的眼光看,MFC還是太稚氣了。我曾經接觸過一些學習Windows程序開發的新人,他們對MFC充滿鄙夷,認為MFC是上個世紀的遺留產物,它概念多、晦澀難懂、代碼量大、界面也丑,他們更傾向于Qt、WPF這樣的新秀。他們的結論是對的,MFC確實是上個世紀的遺留產物;但推導過程不對,MFC與Qt、WPF本質上是一樣的東西,在MFC上遇到的問題,在使用Qt、WPF時極可能也會遇到,不過是早還是晚。只能說“MFC對新人極不友好”。

在MFC同時代,也正是上世紀80、90年代,出現了對后世UI框架設計有極大影響的技術方案:用web瀏覽器作為圖形界面程序的容器。由于篇幅的限制,我這里直接說結論:作為一個整體性的技術方案,它失敗了。失敗的原因可以大致歸為3點:

  • 其一是觀念上的落后。基于html、js、css的網頁技術,最初的設計意圖是解決文檔瀏覽的問題,采用html為主,js、css相輔的設計方式。這樣的設計在界面表現上有優勢,但也僅此而已,其它方面諸如程序生命周期控制、數據處理等就太糟糕了。
  • 其二是基礎設施的不如意。相關的人才與技術儲備太欠缺,所能實現的產出物,無論在功能上還是性能上都無法與MFC、VCL這樣的傳統程序相同并論。
  • 其三是技術開拓者的急功近利。當時熱衷于以瀏覽器作為圖形程序容器的技術方案的廠商,如網景,還有后來的google和facebook,它們的意圖很明顯,就是挑戰微軟的平臺霸權,建立有利于自身的生態環境(說人話就是:招攬開發者、提供生產工具、生產特定的程序、平臺吃流量)。充滿鼓動性的價值觀營銷在具有叛逆屬性的年輕人中可以快速取得影響力,但得不到主流的支持和強勢技術團隊的示范,一切都是空。

盡管在新世紀的第二個10年以web前端為技術基礎的UI框架,如electron、reactive native,取得了喜人的成果,但與上世紀的雛形相比,它們所在的大環境與技術本質已有了根本的區別。

但失敗的方案并不代表沒有借鑒意義。本世紀初出現了一種被稱為“direct ui”的思潮,其中一大觀點就是程序啟動時加載xml文件作為UI。眼亮的同仁一定會說:這不就是資源編輯器莫。對的,這就是現代意義的資源編輯器的雛形。另外也多有程序會在自身嵌入一個web容器來顯示特定內容的UI,至今Android、iOS App上這樣的做法也相當常見。出于篇幅的限制這里的技術因果就不展開了。

上世紀90年代末到本世紀初是UI庫百花齊放的年代,如今在PC領域,為人熟知的Qt、Gtk、wxWidgets都出現在這個時間段,這是與大環境有關。

  • 首先MFC解決了“有無”的問題,接下來就是“好用難用”的問題;
  • 其次由于前一個10年圖形系統的普及,業界在圖形程序的開發上有了大量的人才、技術、經驗上的積累,開發一套UI庫對于小團隊來說也是敢想敢干的事;
  • 再次定制化的需求開始出現,是需要能實現快速開發的程序框架(WTL),還是可以實現跨平臺的程序框架(Qt)?是需要能實現常見功能的中小程序框架(wxWidgets),還是得安裝幾個G的包但可以實現復雜應用的程序框架(WPF)?不同的團隊面對不同的任務,一定會有不同的選擇。
  • 此外當時微軟作為處于壟斷地位但又不思進取的操作系統廠商,也有推波助瀾的作用。本世紀第一個10年,MFC已很老舊,但微軟卻一直沒有給出升級方案;微軟一味將開發者向.Net上推,但遷移成本太高,并且后者的性能問題也遲遲不能解決。于是開發者只能自己想辦法。

Qt是傳統PC領域程序框架集大成者,除了UI,它還提供數據庫、多媒體等功能,已經不是單純的UI框架,而是一套完整的程序開發解決方案;wxWidgets就要輕量級一些;WPF則是微軟官方作為取代曾經的MFC、后來的WinForm的替代方案。

我這里談一下跨平臺開發的一些經驗。問:使用跨平臺的程序框架開發程序,相比于每個目標平臺單獨組建一個開發組,前者有更高的性價比?回答是:不一定。開發程序不僅僅是程序員的事,還涉及到產品策劃、美術、市場運營、第三方技術供應商等方方面面,具體問題要具體分析。事實上資金與人力充足的團隊,更傾向于不同目標平臺組建各自的開發組。

新世紀的第二個10年,以iOS、Android主導的移動平臺興起。Qt推出了移動平臺版本,但終究沒有形成氣候;微軟推出UWP,WPF還是被舍棄了。這又是另一個話題了。

作者:wzsayiie
鏈接:https://www.zhihu.com/question/23480014/answer/658825482
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

總結

以上是生活随笔為你收集整理的MFC和QT等UI框架的特点的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。