- Qt 5.12實(shí)戰(zhàn)
- 朱晨冰 李建英
- 3828字
- 2021-03-26 21:56:33
1.4 Qt和MFC的比較
在當(dāng)今基于C++的圖形界面開發(fā)領(lǐng)域,能與Qt相抗衡的只有MFC。MFC是微軟公司的基礎(chǔ)類庫,自然得天獨(dú)厚,比如開發(fā)深層次的Windows應(yīng)用遠(yuǎn)超Qt,但Qt也有殺手锏,那就是跨平臺。這兩點(diǎn)大家一目了然,下面我們再來比較一下它們的其他特點(diǎn)。
(1)開發(fā)速度
就整體而言,MFC可能會(huì)快捷一些,因?yàn)閃indows平臺的開發(fā)工具大多很智能,因?yàn)榱⒆阌赪indows的開發(fā)人群很廣,從菜鳥到專業(yè)人士(開發(fā)人員一多,技術(shù)參考就多,周圍可以咨詢問題的人就多)。相比較而言,Qt基于Linux,可用的開發(fā)工具不多,而且這些工具大都比較專業(yè),多是第三方的產(chǎn)品,加上這些工具的集成度不高,支持的第三方庫也沒有支持MFC的第三方庫多,因而從這一點(diǎn)看MFC略勝一籌。不過,Qt自從被諾基亞公司收購后,官方發(fā)布了跨平臺集成開發(fā)環(huán)境Qt Creator,之后的走向就不好說。總體感覺就是Qt Creator和VS差距比較大,還需要改進(jìn)。
從庫本身來說,Qt集成的功能比MFC龐大,而且使用的封裝技術(shù)(信號/槽)倍受贊許,比如Qt Script為Qt提供了嵌入式腳本,Qt界面庫支持CSS,所以Qt構(gòu)建出來的界面比MFC要好,且實(shí)現(xiàn)過程也比較容易。為了降低使用Windows SDK開發(fā)的難度以及提高使用Windows SDK開發(fā)的效率,MFC采用的是淺層封裝(最新的2008 sp1加入了BCG的高級界面庫,可能有所改善)Windows SDK。這個(gè)方面相比而言,Qt庫比MFC優(yōu)秀。不過,這兩個(gè)庫久經(jīng)考驗(yàn),穩(wěn)定性都很高,幾乎沒有什么Bug。
(2)運(yùn)行效率
MFC采用淺層封裝,運(yùn)行效率比較高,加上VC對Windows進(jìn)行了針對性的優(yōu)化,因而整體性能是比較高的,但是如果加入第三方庫就不敢保證整體的高性能了。Qt庫比較龐大,封裝層次較深,所以運(yùn)行效率比MFC低,不過在如今主流計(jì)算機(jī)系統(tǒng)的配置下人們不太會(huì)介意這點(diǎn)性能差別了。
(3)應(yīng)用范圍
如今Windows的普及率無人能及,MFC的使用人數(shù)自然較多,相比而言,Qt主要是Linux下的開發(fā)人員在使用。MFC不支持嵌入式開發(fā)(主要是指手機(jī)平臺);而Qt有對應(yīng)的支持模塊,雖然被Java碾壓,但是還有使用空間。
(4)學(xué)習(xí)難度
Qt的封裝方式比較明晰,和系統(tǒng)隔離得比較好,學(xué)習(xí)門檻不高。MFC較難精通,因?yàn)樯钊腴_發(fā)之后還需要了解SDK,否則開發(fā)出的程序比較初級。
(5)偽對象vs真對象
歸根結(jié)底,Qt和MFC的差異在于其設(shè)計(jì)的差異。MFC的根本目的是讓開發(fā)者調(diào)用封裝好的、用C語言編寫的Windows API。但是,這絕非好的面向?qū)ο蟮某绦蛟O(shè)計(jì)模式,因?yàn)樵诤芏鄨龊希覀儽仨毺峁┮粋€(gè)包含15個(gè)結(jié)構(gòu)成員的C語言的struct(結(jié)構(gòu)類型),但是其中只有一個(gè)結(jié)構(gòu)成員是我們需要使用的,或者必須用在調(diào)用函數(shù)中使用參數(shù)的方式來獲得我們需要的結(jié)構(gòu)成員。MFC還有許多讓人摸不著頭腦的地方,比如函數(shù)名就沒有任何連續(xù)性,假設(shè)要?jiǎng)?chuàng)建一個(gè)graphical類,直到調(diào)用creat()以后才會(huì)被創(chuàng)建;對于dialogs類,必須要等到調(diào)用OnInitDialog()才能創(chuàng)建實(shí)例對象,奇怪的是到了views,創(chuàng)建該類的函數(shù)名竟然成了OnInitUpdate()。使用VC/MFC中的庫函數(shù)調(diào)用總是要十分小心,不如Qt可以顧名思義。
(6)消息循環(huán)
MFC是事件驅(qū)動(dòng)的架構(gòu),必須對任何操作對應(yīng)的特定消息做出響應(yīng)。Windows中應(yīng)用程序發(fā)送的信息數(shù)以千計(jì),遺憾的是要厘清這些紛繁蕪雜的消息很困難,通過參考這方面的文檔資料并不能很好地解決這些問題。
Qt的消息機(jī)制建立在SIGNAL()發(fā)送和SLOT()接收的基礎(chǔ)上。這個(gè)機(jī)制是對象間建立聯(lián)系的核心機(jī)制。利用SIGNAL()可以傳遞任何參數(shù),它的功能非常強(qiáng)大,可以直接傳遞信號給SLOT(),因此可以清楚地理解要發(fā)生的事情。一個(gè)類所發(fā)送的信號數(shù)量通常非常少(4個(gè)或者5個(gè)),相關(guān)的幫助文檔資料也非常齊全,這會(huì)讓我們覺得一切盡在掌握之中。信號/槽機(jī)制類似于Java中的listener機(jī)制,不過這種機(jī)制更加輕量級,功能更齊全。
(7)創(chuàng)建界面
MFC無法創(chuàng)建大小動(dòng)態(tài)可變的子窗口,必須重新手動(dòng)修改代碼來改變窗口的位置(這恰好解釋了為什么Windows里的對話框dialog是不可以改變的),這個(gè)問題在軟件進(jìn)行多語言化版本設(shè)計(jì)時(shí)更加嚴(yán)重,因?yàn)樵S多國家或地區(qū)在表達(dá)相同意思時(shí)可能需要更長的詞匯和句子,軟件開發(fā)者必須對每種語言的版本重新修改軟件。
在Qt中,界面需要的任何設(shè)計(jì)都可以手動(dòng)編寫出來,因?yàn)樗芎唵危簽榱说玫揭粋€(gè)按鈕(button),可以將代碼寫為“button=new PushButton("buttonName", MyParentName);”,如果想在按下某個(gè)按鈕以后調(diào)用某段執(zhí)行代碼,則可以編寫為“connect(button, SIGNAL(clicked()),qApp, SLO(action()));”。Qt擁有非常簡單而又不失強(qiáng)大的設(shè)計(jì)機(jī)制,不使用它實(shí)在可惜。
Qt還提供了一個(gè)圖形用戶工具——Qt Designer,可以讓我們完成許多在MFC中不可能完成的任務(wù),比如用預(yù)先填好的內(nèi)容生成列表視圖(listview)、在每個(gè)頁簽(tab)上使用不同的視圖(view)。
Qt Designer生成的代碼可閱讀、可理解,單獨(dú)放在一個(gè)文件中。在編程的同時(shí),我們可以隨心所欲地多次重新生成用戶界面,而不用將控件拖放到設(shè)計(jì)嚴(yán)格限定的位置,因?yàn)榭梢酝ㄟ^設(shè)計(jì)機(jī)制更完美地組織這些控件。
(8)幫助文檔
用戶選擇圖形開發(fā)環(huán)境的時(shí)候,幫助文檔是否周全是左右用戶選擇圖形開發(fā)環(huán)境的重要因素。Visual開發(fā)環(huán)境的幫助文檔MSDN(需要單獨(dú)購買)非常龐大,有10個(gè)CD-ROM之大,涵蓋內(nèi)容廣泛,但難免有泥沙俱下、主題模糊、關(guān)鍵信息不突出的遺憾。MSDN的鏈接設(shè)計(jì)也很糟糕,通過鏈接很難從一個(gè)類跳轉(zhuǎn)到它的父類、子類或者相關(guān)的類。例如,搜索一個(gè)關(guān)鍵字,不管是否直接關(guān)聯(lián),只要包含這個(gè)關(guān)鍵字的信息統(tǒng)統(tǒng)都會(huì)搜索出來。
Qt的文檔設(shè)計(jì)得相當(dāng)優(yōu)秀,可以到https://doc.qt.io/上一睹芳容。Qt的文檔完備且詳細(xì)地覆蓋了Qt的方方面面,然而文檔的整體容量竟然僅有18MB。其中每一個(gè)類和方法都被詳盡描述,巨細(xì)靡遺,舉例充實(shí)。通過Trolltech公司提供的鏈接或者是Qt Assistant工具可以方便地從一個(gè)類或者方法跳轉(zhuǎn)到其他的類。文檔還包含了一個(gè)初學(xué)者教程和一些典型應(yīng)用的例子,同時(shí)還提供了FAQ和郵件列表,方便用戶通過用戶群或Internet來查閱。如果購買了授權(quán),在一天之內(nèi)就會(huì)得到Trolltech公司的技術(shù)支持。實(shí)際上,Qt優(yōu)秀的幫助文檔使得尋求外部幫助的機(jī)會(huì)大大減少。Trolltech公司的宗旨之一是:有如此優(yōu)秀的Qt產(chǎn)品及其幫助文檔,其他外部的技術(shù)支持就是多余的。
總之,MSDN用熟了也很好用、很全面,相關(guān)的背景知識、例子都能找到,而且網(wǎng)上還有豐富的范例程序可以參考。同樣地,僅憑Qt的幫助文檔不足以解決所有問題。
(9)Unicode編碼
使用MFC,如果要顯示Unicode編碼的字符,在編譯鏈接時(shí)就必須用到特殊的參數(shù)(還要改變可執(zhí)行文件執(zhí)行的入口),必須在每個(gè)string前面加上T,將char修改成TCHAR,每個(gè)字符串處理函數(shù)(strcpy()、strdup()、strcat()等)都要改變成其他的字符串處理函數(shù)名。更令人惱火的是,支持Unicode的軟件竟然不能和不支持Unicode編碼的DLL一起工作。這是一個(gè)很嚴(yán)重的問題,但是我們別無選擇。
使用Qt,字符串用QString類來處理,QString類與生俱來就采用Unicode編碼,因而不需要改變?nèi)魏螙|西:不需要在編譯/鏈接時(shí)增添參數(shù),不需要修改代碼,只需要使用QString類即可。QString類功能強(qiáng)大、應(yīng)用廣泛,也不用擔(dān)心Unicode問題。QString類提供了轉(zhuǎn)換為char *和UTF8的函數(shù)。MFC的CString類設(shè)計(jì)相比于Qt的QString類設(shè)計(jì)有著巨大的不同,CString類以char *為基礎(chǔ)提供的功能很少,它的特點(diǎn)是當(dāng)需要char *類型時(shí)可以直接使用CString類。乍看起來這好像是優(yōu)點(diǎn),實(shí)質(zhì)上有很大缺陷,特別是可以直接修改char *內(nèi)容而不用更新類,在轉(zhuǎn)變?yōu)閁nicode時(shí)會(huì)遭遇到很大的麻煩(CString類隨編譯選項(xiàng)可以是Unicode版)。相反,QString類在內(nèi)部以Unicode編碼方式來存儲字符串,需要時(shí)提供char *功能,實(shí)際上很少用到char *,因?yàn)檎麄€(gè)Qt的API用文本的方式響應(yīng)QString參數(shù)。QString還附帶了許多其他的功能,比如自動(dòng)分享QString的內(nèi)容。總之QString是一個(gè)非常強(qiáng)大的類,需要用到它的地方很多。
(10)支持軟件的多語種功能
MFC可以支持軟件的多語種功能,需要將每一個(gè)語種的字符串放在一個(gè)字符串表中,在代碼中需要之處調(diào)用LoadString(IDENTIFIET),然后把這些字符串資源轉(zhuǎn)化到DLL中,這些字符串對應(yīng)到所需要的語言,改變圖形界面,再通過程序調(diào)用這個(gè)DLL。整個(gè)過程非常煩瑣,可謂牽一發(fā)而動(dòng)全身。
Qt支持軟件多語種的方式有所不同,只需要將字符串置于函數(shù)tr()中,可以直接在代碼中改變字符串的引用。Qt Linguist(Qt的一個(gè)工具)能夠提取所有待翻譯的字符串并按照對應(yīng)語種的用戶界面顯示出來,非常適合進(jìn)行用戶界面的多語種翻譯。它的功能齊全,可以通過查詢字典數(shù)據(jù)顯示出對應(yīng)語種的字符串內(nèi)容,正確顯示出Unicode編碼,以快捷方式檢測出未翻譯的字符串,檢測字符串修改的情況等。這個(gè)工具甚至可以提供給沒有任何編程經(jīng)驗(yàn)的翻譯人員用于翻譯軟件的用戶界面。該軟件的發(fā)布遵循GPL版權(quán)規(guī)則,可以由開發(fā)者根據(jù)具體的開發(fā)需求來修改。翻譯之后的文檔保存在XML中,符合軟件復(fù)用的原則。由此可見,為軟件增加一種新的語言版本僅僅是用Qt Linguist工具生成一個(gè)新的文件而已。
(11)資源問題
使用MFC時(shí),一部分開發(fā)過程要依靠“資源”(Resource),在很多的案例中開發(fā)者都必須使用它們。這樣會(huì)導(dǎo)致如下后果:除了Visual Studio,很難使用其他的工具來完成開發(fā)。資源編輯器僅有有限的功能,比如通過Dialog編輯器不能改變所有的屬性。
Qt并沒有資源的概念,解決了MFC所遇到的問題。Qt提供了一個(gè)界面設(shè)計(jì)器,以可視化的方式來設(shè)計(jì)界面,并把設(shè)計(jì)后生成的代碼存儲到一個(gè)腳本文件中。
(12)價(jià)格
用戶一旦購買了Visual Studio,就將免費(fèi)獲得MFC SDK。Qt在UNIX上可以免費(fèi)獲得遵守GPL版權(quán)規(guī)則的版本,現(xiàn)在也可以免費(fèi)獲得Windows平臺上的GPL版本。如果要開發(fā)不公開源代碼的軟件,則必須購買Qt的授權(quán)。在特定平臺下,每個(gè)開發(fā)者都可購買一個(gè)永久性授權(quán),并可獲得一年的技術(shù)支持。
(13)發(fā)布
在發(fā)布基于MFC的軟件時(shí),必須依靠存儲在客戶計(jì)算機(jī)上的MFC,但是這是不安全的,同樣是MFC42.dll,基于相同的庫可得到3個(gè)不同的版本。因而需要檢查是否擁有正確的MFC42.dll版本,如果版本不對,就升級它。但是,升級MFC42.dll會(huì)改變很多軟件的行為。這讓開發(fā)者感覺很不好,如果在安裝軟件以后導(dǎo)致用戶的計(jì)算機(jī)死機(jī)了,該怎么辦呢?
Qt沒有這個(gè)風(fēng)險(xiǎn),因?yàn)镼t壓根就沒有“升級整個(gè)系統(tǒng)”的概念。不過,開發(fā)的軟件若不是基于同一個(gè)版本的Qt來運(yùn)行的,則會(huì)有潛在的問題。
- Vue.js設(shè)計(jì)與實(shí)現(xiàn)
- GAE編程指南
- Kibana Essentials
- OpenDaylight Cookbook
- C語言程序設(shè)計(jì)案例教程(第2版)
- JavaScript+jQuery網(wǎng)頁特效設(shè)計(jì)任務(wù)驅(qū)動(dòng)教程(第2版)
- Learning C++ Functional Programming
- Mastering Julia
- jQuery從入門到精通 (軟件開發(fā)視頻大講堂)
- Java持續(xù)交付
- Python面向?qū)ο缶幊蹋簶?gòu)建游戲和GUI
- R大數(shù)據(jù)分析實(shí)用指南
- ASP.NET程序設(shè)計(jì)教程
- 智能手機(jī)APP UI設(shè)計(jì)與應(yīng)用任務(wù)教程
- Android應(yīng)用開發(fā)深入學(xué)習(xí)實(shí)錄