首頁技術(shù)文章正文

C/C++技術(shù)知識點(diǎn): Qt和MFC比較

更新時(shí)間:2017-11-30 來源:黑馬程序員 瀏覽量:

MFC(微軟基礎(chǔ)類庫)是專門為windows設(shè)計(jì)的一個(gè)用于開發(fā)圖形用戶界面的類庫。MFC或多或少使用了面向?qū)ο蟮姆椒òb了Win32的API,正因如此,這些API有時(shí)是C++,有時(shí)是C,甚至是C和C++的混合體。

Qt這個(gè)C++的圖形庫由Trolltech在1991年左右開發(fā)。它可以運(yùn)行在Windows,Mac OS X, Unix,還有像Sharp Zaurus這類嵌入式系統(tǒng)中。Qt是完全面向?qū)ο蟮摹?/p>

Document/View model

MFC編程需要使用Document/View模式以及模板(template),如果不使用的話,編程將變得異常困難。而且,模板(template) 設(shè)定了固定的結(jié)構(gòu),若所需結(jié)構(gòu)乃模板未定義之結(jié)構(gòu),則編程難已。例如,劃分一區(qū)域使顯示兩個(gè)視圖(view)于兩個(gè)文檔(document)。還有一個(gè)經(jīng)常的問題是:模板(template)創(chuàng)建了視圖(view)卻無法訪問(access)它,文檔(document)要做完所有事情,但是這經(jīng)常會(huì)出現(xiàn)問題。

Qt不強(qiáng)制使用任何設(shè)計(jì)模式。如果你認(rèn)為恰當(dāng),使用Document/view沒有任何問題。不使用也沒有任何問題。

偽對象 vs 真對象

歸根結(jié)底,Qt和MFC的差異在于其設(shè)計(jì)的差異。

MFC的根本目的是訪問包裝起來的用C語言寫的windows的API。 這絕非好的面向?qū)ο蟮脑O(shè)計(jì)模式,在很多地方,你必須提供一個(gè)包含15個(gè)成員的C語言的struct,但是其中只有一個(gè)與你所期望的相關(guān),或者必須用舊式的參數(shù)來調(diào)用你的函數(shù)。

Qt恰恰相反,它的架構(gòu)明顯是經(jīng)過精心設(shè)計(jì)的面向?qū)ο蟮?。Qt因此在命名,繼承,類的組織等方面保持了優(yōu)秀的一致性。你只需要提供唯一一個(gè)方法的參數(shù),僅此一個(gè)。在不同的類中調(diào)用方式也是有很強(qiáng)的連貫性。返回值也很有邏輯性。所有一切達(dá)到了簡單和強(qiáng)大的和諧統(tǒng)一。一旦你使用了其中一個(gè)類,其他的類也就觸類旁通,因?yàn)樗麄兪且恢碌摹?/p>

消息循環(huán)

MFC是事件驅(qū)動(dòng)的架構(gòu)。要執(zhí)行任何操作,都必須是對特定的消息作出響應(yīng)。Windows對應(yīng)用程序發(fā)送的

信息數(shù)以千計(jì),遺憾的是,要分清楚這些分繁蕪雜的消息是很困難的,并且關(guān)于這方面的文檔并不能很好的解決這些問題。

Qt的消息機(jī)制是建立在SIGNAL()發(fā)送和SLOT()接受的基礎(chǔ)上的。這個(gè)機(jī)制是對象間建立聯(lián)系的核心機(jī)制。利用SIGNAL()可以傳遞任何的參數(shù)。他的功能非常的強(qiáng)大??梢灾苯哟髠鬟f信號給SLOT(),因此可以清楚的理解要發(fā)生的事情。一個(gè)類所發(fā)送的信號的數(shù)量通常非常的小(4或者5),并且文檔也非常的齊全。這讓你感覺到一切盡在掌握之中。SIGNAL/SLOT機(jī)制類似于Java中l(wèi)istener機(jī)制,不過這種機(jī)制更加輕量級,功能更齊全。

創(chuàng)建界面

MFC無法創(chuàng)建大小動(dòng)態(tài)可變的子窗口,必須重新手動(dòng)修改代碼來改變窗口的位置(這恰好解釋了為什么windows里的dialog是不可以改變的)這個(gè)問題在軟件進(jìn)行國際化翻譯的時(shí)候更加嚴(yán)重,因?yàn)樵S多國家表達(dá)相同意思需要更長的詞匯和句子,必須要對每個(gè)語言的版本重新修改自己的軟件。

在Qt中,任何東西都可以手動(dòng)的敲出來,因?yàn)樗芎唵危簽榱说玫揭粋€(gè)button,可以這樣些

button = new PushButton( "buttonName", MyParentName );

如果想在按下某個(gè)按鈕以后想調(diào)用某斷代碼的執(zhí)行,可以這樣寫:

connect( button, SIGNAL( clicked() ), qApp, SLOT( action() ) );

Qt擁有非常簡單而又不失強(qiáng)大的layout機(jī)制,以至于不使用它就是在浪費(fèi)時(shí)間了。

Qt還提供了一個(gè)圖形用戶工具,Qt Designer,可以用來幫助建立用戶界面??梢孕薷乃褂玫娜魏慰丶膶傩浴2挥脤⑺麄兎旁趪?yán)格的位置,可以通過layout完美的組織他們。這個(gè)工具所產(chǎn)生的代碼我們是可以實(shí)際上閱讀并且可以理解的。生成的代碼單獨(dú)放在一個(gè)文件里,在編程的同時(shí),你可以隨心所欲的多次重新生成用戶界面。

Qt Designer可以讓你完成許多在MFC中不可能完成的任務(wù),比如用預(yù)先填好的生成listview,在每個(gè)tab上用不同的view來使用tab 控制。

幫助文檔

用戶選擇圖形開發(fā)環(huán)境的時(shí)候,幫助文檔是否周全是左右其選擇的重要因素。Visual的開發(fā)環(huán)境的幫助文檔MSDN(這個(gè)還要單獨(dú)掏錢購買)非常的龐大,有10個(gè)CDROM光盤。他包羅萬象,涵蓋廣泛。但是難免有泥沙俱下,主題模糊,關(guān)鍵信息不突出的遺憾。其鏈接設(shè)計(jì)的也很糟糕,通過鏈接很難從一個(gè)類跳轉(zhuǎn)到其父類或者子類以及相關(guān)的類。如果你搜索一個(gè)關(guān)鍵字,不管是Visual C++, Visual J++, Visual Basic,只要包含這些關(guān)鍵字的信息統(tǒng)統(tǒng)的返回來。

Qt的文檔完備且詳細(xì)的覆蓋了Qt的方方面面,竟然僅有18M。每一個(gè)類和方法都被詳盡描述,巨細(xì)靡遺,舉例充實(shí)。通過Trolltech公司提供的鏈接或者是Qt Assistant工具,可以方便的從一個(gè)類或者方法跳轉(zhuǎn)到其他的類。文檔還包含了一個(gè)初學(xué)者教程和一些典型應(yīng)用的例子。同時(shí)還提供了FAQ和郵件列表,方便通過Internet或者用戶群來查閱。如果你購買了授權(quán),在一天之內(nèi)你將會(huì)得到Trolltech公司的技術(shù)支持。

Unicode

使用MFC,如果要顯示unicode,在編譯鏈接的時(shí)候必須用到特殊的參數(shù)(和改變可執(zhí)行文件執(zhí)行的入口),必須在每個(gè)string前面加上T,將 char修改成TCHAR,每個(gè)字符串處理函數(shù)(strcpy(), strdup(), strcat()...... )都要改變成另外的函數(shù)名。更令人惱火的是支持Unicode的軟件竟然不能和不支持Unicode的DLL一起工作。當(dāng)使用外部DLL來開發(fā)的時(shí)候這是個(gè)很嚴(yán)重的問題,但是你毫無選擇。

使用Qt,字符串用QString來處理,其本身是與生俱來的Unicode.不需要改變什么東西。不要在編譯/鏈接時(shí)候增添參數(shù),不要修改代碼,只需要使用QString就可以了。

QSting類功能強(qiáng)大,你可以廣泛的使用它,并且不要擔(dān)心Unicode問題。這使得轉(zhuǎn)換為Unicode非常的方便。QSting提供了轉(zhuǎn)換為char * 和UTF8的函數(shù)。

顯然,MFC的CString的設(shè)計(jì)相比于Qt的QString設(shè)計(jì)有著巨大的不同。CString以char *為基礎(chǔ)提供了很少的功能。它的優(yōu)點(diǎn)是當(dāng)需要char *類型的時(shí)候,可以直接使用CString類型。乍看起來這個(gè)好像是個(gè)優(yōu)點(diǎn),其實(shí)實(shí)質(zhì)上還是有很大的缺陷的,特別是可以直接修改char * 而不要更新類。在轉(zhuǎn)變?yōu)閁nicode的時(shí)候這個(gè)也碰到很大的麻煩。

相反,QString在內(nèi)部以unicode存儲(chǔ)string,需要時(shí)提供char *功能。實(shí)際上很少用到char *,因?yàn)檎麄€(gè)Qt的API用文本的方式響應(yīng)QString參數(shù)。QString還附帶許多其他的功能,比如自動(dòng)分享QString的內(nèi)容。這是一個(gè)非常強(qiáng)大的類,你會(huì)喜歡在很多地方用它的。

國際化

使用MFC是可以國際化的,但是需要將每一個(gè)字符串放在一個(gè)字符串表中,在代碼中到處使用LoadString(IDENTIFIET)。然后轉(zhuǎn)化這些資源到DLL中,翻譯字符串到所需要的語言,改變圖形界面,然后調(diào)用程序使用這個(gè)DLL。整個(gè)過程是如此的繁瑣,可謂牽一發(fā)而動(dòng)全身。考慮的事情要面面俱到。

使用Qt的時(shí)候,只需要將字符串置于函數(shù)tr()中,在程序開發(fā)中這算是舉手之勞??梢灾苯釉诖a中改變字符串的參考。Qt Linguist,Qt的一個(gè)工具,能夠提取所有待翻譯的string并按照友好的界面顯示出來。這個(gè)用戶界面非常適合翻譯,使用字典,顯示字符串內(nèi)容,恰當(dāng)?shù)膗nicode顯示,快捷方式?jīng)_突檢測,檢測未翻譯的字符串,檢測字符串修改情況,功能齊全。這個(gè)軟件可以供沒有任何編程經(jīng)驗(yàn)的翻譯者使用。同時(shí)該軟件在GPL的版權(quán)下發(fā)布,可以按照你的需求來修改它。

翻譯以后的文檔保存在XML中,適合軟件復(fù)用的原則。為軟件增加一種新的語言版本僅僅是用Qt Linguist產(chǎn)生一個(gè)新的文件而已。

resources問題

使用MFC,一部分開發(fā)過程要依靠“resources”,在很多的案例中開發(fā)者必須使用他們。這樣會(huì)導(dǎo)致如下的后果:

出了Visual Studio,你很難使用其他的工具來完成開發(fā)。

資源編輯器僅有有限的功能,比如:通過Dialog編輯器不可能改變所有的屬性,一些屬性可以改變,另一些屬性則不可能改變。(譯者注:下面還有兩條陳述MFC缺點(diǎn)的實(shí)例,但我感覺這些已經(jīng)夠說明問題了,暫時(shí)刪節(jié)不譯)

然而Qt并沒有資源的概念,這就解決了以上所提到的問題。Qt提供了一個(gè)腳本使得能將編入你的代碼。對于界面設(shè)計(jì),Qt Designer則創(chuàng)建了可讀的代碼。

發(fā)布

在發(fā)布基于MFC的軟件時(shí),必須依靠存在于客戶電腦上的MFC。但是這是不安全的,同樣是MFC42.dll,可以基于相同的庫得到3個(gè)不同的版本。通常,需要檢查是否擁有正確的MFC42.dll版本,如果不是,就升級它。但是升級MFC42.dll會(huì)改變很多軟件的行為。這讓我感到很不舒服,如果用戶在安裝我的軟件以后導(dǎo)致其機(jī)器死機(jī)該怎么辦?

Qt則沒有這個(gè)風(fēng)險(xiǎn),因?yàn)镼t壓根就沒有“升級整個(gè)系統(tǒng)”這個(gè)概念。


本文版權(quán)歸黑馬程序員C/C++學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!


作者:黑馬程序員C/C++培訓(xùn)學(xué)院


首發(fā):http://c.itheima.com/


分享到:
在線咨詢 我要報(bào)名
和我們在線交談!