Qt和MFC的比較

2021-01-12 IT學習
IT之外,畫畫是我另外的愛好。

Qt和MFC的比較

在當今基於C++的圖形界面開發領域,能與Qt相抗衡的也只有MFC,MFC是微軟公司的基礎類庫,自然得天獨厚,比如開發深層次的Windows應用,MFC當然遠超Qt,但Qt也有殺手鐧,那就是跨平臺。這兩點大家一目了然。下面我們再來比較它們的其他特點。

(1)開發速度

就整體而言,MFC可能會快捷一些,因為Windows平臺的開發工具大多很智能,因為立足於Windows的開發人群很廣,從菜鳥到專業人士(開發人員一多,技術參考就多,周圍可以諮詢問題的人就多)。相比較而言,Qt基於Linux,可用的開發工具不多,而且這些工具大都比較專業,多是第三方的產品,加上這些工具的集成度不高,支持的第三方庫也沒有支持MFC的第三方庫多,因而從這一點看,MFC略勝一籌。不過,Qt自從被諾基亞公司收購後,官方發布了跨平臺集成開發環境Qt Creator,之後的走向就不好說了,作者個人的總體感覺是Qt Creator和VS差距比較大,還需要改進。

從庫本身來說,Qt集成的功能比MFC龐大,而且使用的封裝技術(信號/槽)倍受讚許,比如Qt Script為Qt提供了嵌入式腳本,Qt界面庫支持CSS,所以Qt構建出來的界面比MFC要好,且實現過程也比較容易。為了降低使用Windows SDK開發的難度以及提高使用Windows SDK開發的效率,MFC採用的是淺層封裝(最新的2008 sp1加入了BCG的高級界面庫,可能有所改善)Windows SDK。這個方面相比而言,Qt庫比MFC優秀。不過,這兩個庫都久經時間的考驗,穩定性都很高,幾乎沒有什麼Bug。

(2)運行效率

MFC採用淺層封裝,運行效率比較高,加上VC對Windows進行了針對性的優化,因而整體性能是比較高的,但是如果加入第三方庫就不敢保證整體的高性能了。Qt庫比較龐大,封裝層次較深,所以運行效率比MFC低,但是在如今主流計算機系統的配置下,人們還會介意這點性能差別嗎?(反正大家都不介意C#對性能略微拉低的影響了。)

(3)應用範圍

如今Windows的普及率無人能及,MFC的使用人數自然就多,相比而言,Qt主要是Linux下的開發人員在使用。MFC不支持嵌入式開發(主要是指手機平臺),而Qt有對應的支持模塊,雖然這一手機開發領域被Java碾壓,但總歸還是有Qt的使用空間。

(4)學習難度

Qt的封裝方式比較明晰,和系統隔離得比較好,作者個人覺得學習的門檻不高。而MFC則較難精通,因為深入開發之後還需要了解SDK,否則開發出的程序比較初級。

(5)偽對象vs真對象

歸根結底,Qt和MFC的差異在於其設計的差異。MFC的根本目的是讓開發者調用封裝好的、用C語言編寫的Windows API。但是,這絕非好的面向對象的程序設計模式,因為在很多場合,我們必須提供一個包含15個結構成員的C語言的struct(結構類型),但是其中只有一個結構成員是我們需要使用的,或者必須用在調用函數中使用參數的方式來獲得我們需要的結構成員。MFC還有許多讓人摸不著頭腦的地方,例如函數名沒有任何連續性,假如我們創建了一個graphical類,直到調用了creat()以後該類才會被創建。然而對於dialogs類,必須要等到調用OnInitDialog()才能創建這個類的實例對象。奇怪的是到了views,創建該類的函數名竟然成了OnInitUpdate(),使用VC/MFC中的庫函數調用總是要十分小心,不如Qt那樣一看函數名就知道對應函數的作用是什麼。

(6)消息循環

MFC是事件驅動的架構。必須對任何操作對應的特定消息做出響應。Windows中應用程式發送的信息數以千計,遺憾的是,要釐清這些紛繁蕪雜的消息很困難,通過參考這方面的文檔資料並不能很好地解決這些問題。

Qt的消息機制建立在SIGNAL()發送和SLOT()接收的基礎上。這個機制是對象間建立聯繫的核心機制。利用SIGNAL()可以傳遞任何參數,它的功能非常強大,可以直接傳遞信號給SLOT(),因此可以清楚地理解要發生的事情。一個類所發送的信號數量通常非常少(4個或者5個),相關的幫助文檔資料也非常齊全。這讓我們會覺得到一切盡在掌握之中。信號/槽(Signal/Slot)機制類似於Java中的listener機制,不過這種機制更加輕量級,功能更齊全。

(7)創建界面

MFC無法創建大小動態可變的子窗口 ,必須重新手動修改代碼來改變窗口的位置(這恰好解釋了為什麼Windows裡的對話框dialog是不可以改變的),這個問題在軟體進行多語言化版本設計時更加嚴重,因為許多國家或地區在表達相同意思時可能需要更長的詞彙和句子,於是軟體開發者必須對每種語言的版本重新修改自己的軟體。

在Qt中,界面需要的任何設計都可以手動編寫出來,因為它很簡單:為了得到一個按鈕(button),可以將代碼寫為「button = new PushButton( "buttonName", MyParentName );」,如果想在按下某個按鈕以後調用某段執行代碼,則可以編寫為「connect(button, SIGNAL(clicked()), qApp, SLOT(action()));」。Qt擁有非常簡單而又不失強大的設計機制,不使用它實在可惜。

Qt還提供了一個圖形用戶工具——Qt Designer,可以用來協助建立用戶界面。可以使用Qt Designer修改所使用的任何控制項的屬性,不用將這些控制項拖放到設計嚴格限定的位置,因為可以通過設計機制更完美地組織這些控制項。

Qt Designer這個工具所生成的代碼可閱讀、可理解。所生成的代碼單獨放在一個文件中,在編程的同時,我們可以隨心所欲地多次重新生成用戶界面。

Qt Designer可以讓我們完成許多在MFC中不可能完成的任務,比如用預先填好的內容生成列表視圖(listview),在每個頁籤(tab)上使用不同的視圖(view)。

(8)幫助文檔

用戶選擇圖形開發環境的時候,幫助文檔是否周全是左右用戶選擇圖形開發環境的重要因素。Visual開發環境的幫助文檔MSDN(這個還要單獨掏錢購買)非常龐大,有10個CD-ROM光碟容量之大,它包羅萬象,涵蓋廣泛,但難免有泥沙俱下、主題模糊、關鍵信息不突出的遺憾。MSDN的連結設計也很糟糕,通過連結很難從一個類跳轉到它的父類或者子類以及相關的類。如果搜索一個關鍵字,結果找到的內容不管是否直接關聯,只要包含這個關鍵字的信息統統都會搜索出來,讓用戶再從中選擇。

Qt的文檔設計得相當優秀,可以到https://doc.qt.io/上面一睹它的芳容。Qt的文檔完備且詳細地覆蓋了Qt的方方面面,然而文檔的整體容量竟然僅有18MB。其中每一個類和方法都被詳盡描述,巨細靡遺,舉例充實。通過Trolltech公司提供的連結或者是Qt Assistant工具可以方便地從一個類或者方法跳轉到其他的類。文檔還包含了一個初學者教程和一些典型應用的例子。同時還提供了FAQ和郵件列表,方便用戶通過用戶群或通過Internet來查閱。如果我們購買了授權,在一天之內就會得到Trolltech公司的技術支持。實際上,Qt優秀的幫助文檔使得尋求外部幫助的機會大大減少。Trolltech公司的宗旨之一是:有如此優秀的Qt產品及其幫助文檔,其他外部的技術支持就是多餘的。

總之,MSDN用熟了也很好用、很全面,相關的背景知識、例子都能找到,而且網上還有豐富的範例程序可以參考。同樣的,僅憑Qt的幫助文檔也絕對不足以解決所有問題,以作者的親歷,在網上只找到了一個Qt中文論壇,提過幾個問題,有的問題給出了解決辦法,有的問題則沒人回答,最後還要靠自己試。

(9)Unicode編碼

使用MFC,如果要顯示Unicode編碼的字符,在編譯連結時必須用到特殊的參數(還要改變可執行文件執行的入口),必須在每個string前面加上T,將char修改成TCHAR,每個字符串處理函數(strcpy()、strdup()、strcat()等等)都要改變成另外的字符串處理函數名。更令人惱火的是,支持Unicode的軟體竟然不能和不支持Unicode編碼的DLL一起工作。這是一個很嚴重的問題,但是我們卻別無選擇。

使用Qt,字符串用QString類來處理,QString類與生俱來就採用Unicode編碼,因而不需要改變任何東西:不需要在編譯/連結時增添參數,不需要修改代碼,只需要使用QString類即可。QString類功能強大、應用廣泛,也不用擔心Unicode問題。QString類提供了轉換為char * 和UTF8的函數。MFC的CString類設計相比於Qt的QString類設計則有著巨大的不同,CString類以char *為基礎提供的功能很少,它的特點是當需要char *類型時,可以直接使用CString類。乍看起來這好像是個優點,實質上有很大缺陷,特別是可以直接修改char *內容而不用更新類,在轉變為Unicode時就會遭遇到很大的麻煩(CString類隨編譯選項可以是Unicode版)。相反,QString類在內部以Unicode編碼方式來存儲字符串,需要時提供char *功能,實際上很少用到char *,因為整個Qt的API用文本的方式響應QString參數。QString還附帶了許多其他的功能,比如自動分享QString的內容。總之QString是一個非常強大的類,需要用到它的地方很多。

(10)支持軟體的多語種功能

MFC可以支持軟體的多語種功能,需要將每一個語種的字符串放在一個字符串表中,在代碼中需要之處調用LoadString(IDENTIFIET),然後把這些字符串資源轉化到DLL中,這些字符串對應到所需要的語言,改變圖形界面,再通過程序調用這個DLL。整個過程是如此的煩瑣,可謂牽一髮而動全身。

Qt支持軟體多語種的方式有所不同,只需要將字符串置於函數tr()中,可以直接在代碼中改變字符串的引用。Qt Linguist(Qt的一個工具)能夠提取所有待翻譯的字符串並按照對應語種的用戶界面顯示出來,這個工具非常適合進行用戶界面的多語種翻譯,它功能齊全:通過查詢字典數據顯示出對應語種的字符串內容,正確顯示出Unicode編碼,以快捷方式檢測出未翻譯的字符串,檢測字符串修改的情況。這個工具甚至可以提供給沒有任何編程經驗的翻譯人員用於翻譯軟體的用戶界面。該軟體的發布遵循GPL版權規則,開發者可以根據具體的開發需求來修改它。翻譯之後的文檔保存在XML中,符合軟體復用的原則。由此可見,為軟體增加一種新的語言版本僅僅是用Qt Linguist工具生成一個新的文件而已。

(11)資源問題

使用MFC時,一部分開發過程要依靠「資源」(resources),在很多的案例中開發者都必須使用它們。這樣會導致如下後果:除了Visual Studio,很難使用其他的工具來完成開發。資源編輯器僅有有限的功能,比如通過Dialog編輯器不能改變所有的屬性。

然而,Qt並沒有資源的概念,這就解決了MFC所遇到的問題。Qt提供了一個界面設計器以可視化的方式來設計界面,並把設計後生成的代碼存儲到一個腳本文件中。

(12)價格

用戶一旦購買了Visual Studio,將免費獲得MFC SDK。Qt在UNIX上可以免費獲得遵守GPL版權規則的版本(現在可以免費獲得Windows平臺上的GPL版本)。如果要開發不公開原始碼的軟體,則必須購買Qt的授權。在特定平臺下,每個開發者購買一個永久性授權,並可獲得一年的技術支持。

(13)發布

在發布基於MFC的軟體時,必須依靠存儲在客戶計算機上的MFC,但是這是不安全的,同樣是MFC42.dll,基於相同的庫可得到3個不同的版本。因而需要檢查是否擁有正確的MFC42.dll版本,如果版本不對,就升級它。但是,升級MFC42.dll會改變很多軟體的行為。這讓開發者感到很不「爽」,如果用戶在安裝軟體以後導致用戶的計算機死機了,該怎麼辦呢?

Qt則沒有這個風險,因為Qt壓根就沒有「升級整個系統」的概念。不過,如果開發的軟體不是基於同一個版本的Qt來運行,還是會有潛在的問題。

相關焦點

  • MFC下的cstring與char互相轉換方法
    Mfc下的cstring與char互相轉換方法本次課程主要來為大家講一下平時我們總是在mfc下環境開發中使用的char類型的數組和cstring格式的轉換,還有在qt下該如何轉換,送給有需要的小夥伴們。
  • qt creator連接資料庫並實現用戶登錄和註冊相關的開發源碼詳解
    項目最終實現效果圖具體代碼詳解1 如何給qt界面設置相關的圖片呢?首先我們新建一個基於對話框的程序,名字自己定義即可。遇到問題不要著急,從程序邏輯和原理上去找相關的原因,最終就能解決相關的問題的。2 如何連接相關的資料庫,進行資料庫相關的調用關聯資料庫最重要的就是調用mysql進行相關的用戶註冊信息的記錄,我們為何要使用sql呢?
  • Qt 6 發布在即,Debian Qt 維護者決定卸任
    在維護 Debian 中的 Qt 軟體包相當長一段時間後,Dmitry 和 Lisandro 決定卸任。
  • QT5.12版本下編譯和搭建QTXlsx庫讀取Excel表格第二講
    解決方法將build下的這個文件夾下的內容拷貝到qt的安裝目錄下。如我的構建路徑是:F:\nhy\Source\QT512\excel\build-qtxlsx-Desktop_Qt_5_12_1_MinGW_64_bit-Debug\mkspecsqt的安裝路徑也就是拷貝路徑是E:\QT\QT5.12\5.12.1\mingw73_64\mkspecs,再進行構建就成功了哦。
  • Ubuntu20.04 + Qt5.14.2開發環境配置
    1、開發環境要求Ubuntu版本:ubuntu-20.04.1-desktop-amd64Qt版本:qt-opensource-linux-x64-5.14.2虛擬機版本2、Qt的安裝配置(1) Qt的下載考慮到下載速度問題,可在清華大學開源軟體鏡像站點下載Qt5.14.2的版本:「https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.14/5.14.2/」,在這個網頁上下載「qt-opensource-linux-x64
  • 義縣遊學電子科技:qt5.14.2在win10平臺打包步驟
    qt打開項目後,選擇發布模式, 然後點擊編譯.這時就會在構建目錄中出現一些含有項目名.exe的文件了.我這裡的pro1.exe4.在開始菜單找qt,然後打開qt5.14.2(mw7.3.0 64-bit)的命令行窗口,打開後輸入:cd D:\2然後使用 windeployqt 工具命令:windeployqt 項目名.exe
  • qt5.15.2在Ubuntu系統安裝完成後無法啟動qtcreator的解決方法
    1.qtcreator中沒有c++編譯器,需要使用命令:sudo apt install build-essential重新打開qt creator即可自動識別安裝的編譯器了.這個命令將安裝一堆新包,包括
  • qt5.12下繼承於Qdialog的類調用slot函數編譯錯誤匯總
    最近由於項目需要,需要使用qt做一套連接資料庫並且實現用戶登錄,註冊的界面,但是做起來卻很費勁,出現了一堆奇怪的編譯錯誤。這個時候,在qt下先執行qmake,然後再重新構建,最後看一下是否還有錯誤。如果還是一堆堆的錯誤,那麼繼續把報錯的h文件和cpp文件,採用相同的保存方式。經過修改,這個是可以達到解決編譯錯誤的修改的。但是如果代碼本身的格式就是代籤名的,還是出錯的話,我們只能在這個機器上重新新建工程,複製粘貼進行實現了。
  • QT環境開發下根據excel表格導入數據源碼
    將excel表格中的內容進行讀取---qt下excel表格相關的開發//插入新數據for (int i = nStartRow + 1, r = 0; i < rowcnt; i++, r++ )
  • Qt Creator 4.12.0 發布,QT 集成開發環境
    Qt Creator 4.12.0 現已發布,此版本值得關注的更新包括有:Marketplace Qt Creator 4.12 允許用戶瀏覽和搜索Bare metal 得到了對 RL78 和各種調試器的支持,並對 MCU 的支持進行了幾次更新和修復。有關更廣泛的改進列表,可參見更改日誌。
  • Qt程序打包三部曲,從應用程式到安裝包
    Qt使用自帶的windeployqt 處理依賴庫生成exe來發布軟體。Qt使用自帶的windeployqt 處理依賴庫生成exe來發布軟體。準備exe1.程序要想發布,在編譯器編譯一定要選擇「release」而不是「debug」,編譯成release版本
  • Qt 5.14.2超詳細安裝教程,不會來打我
    如何下載這裡咱們安裝Qt5.14.2(不要問為什麼不裝更新版本的,從Qt5.15.0起,對於開源用戶,Qt官方不再提供獨立安裝文件,所以源碼安裝太麻煩,以後再研究^_^)官網下載連結:http://download.qt.io/archive/qt/5.14/5.14.2/
  • 軟體特攻隊|Qt Creator,Windows/Linux安裝大全
    /qt-opensource-linux-x64-5.11.1.run3、完成安裝三、注意事項在Windows環境下,不要使用XP系統作為環境;在Linux環境下,如果Linux版本過低,如ubuntu
  • 類似Qt 的「跨平臺 GUI 框架 GOSP」時隔一年有重大更新
    但Qt太重量級了(Qt需要很多的RAM和ROM),因此我開發了GOSP這個框架。GOSP在不依賴Qt的前提下,提供了非常類似Qt的API接口,僅需要幾百KB的硬體資源(比Qt小的多),能運行在Qt不支持的低性能領域(對Qt形成補充),適用於嵌入式開發。
  • Qt5.12.2+Opencv4.2配置動態連結庫以用Qt調用Opencv進行創作
    二、軟體安裝及環境變量配置1、Qt creator安裝(1)Qt安裝本教程針對之前下載的Qt 5.12.2進行安裝演示l 點擊下載好的qt-opensource-windows-x86l 然後點擊下一步l 選擇安裝文件夾,默認為C盤,由於文件太大建議安裝到其他盤,選擇好安裝路徑後點擊下一步l 選擇如下組件:Qt5.12.2中的MinGW7.3.0 32-bit和
  • KDE 社區稱 Qt 公司正考慮僅面向付費用戶提供新版本
    就此引發的各種討論,Qt 公司進行了簡短的回應,大意是說這些內容不能代表 Qt 公司的觀點和計劃,最後還表示 Qt 公司為自己致力於客戶、開源和 Qt 治理模型的理念而感到自豪首先有必要說明 KDE 社區、Qt 項目和 Qt 公司這三者之間的關係: KDE 基於 Qt 框架開發,因此 KDE 社區既受益於 Qt 也直接為 Qt 貢獻代碼 Qt 既背靠著擁有雄厚資金實力的 Qt 公司,也從龐大且知名的 KDE 社區中獲益甚多 Qt 公司受益於 KDE 社區,因為大量開源貢獻者、開發者和社區專家幫助其改進
  • C++學習教程,QT飛機大戰教程(含詳細步驟教程二)
    添加敵機類中的成員函數和成員屬性實現成員函數敵機出場測試敵機9.1 創建敵機文件和類創建EnemyPlane類以及生成對應的文件創建好後生成enemyPlane.h 和 enemyPlane.cpp兩個文件9.2 敵機成員函數和成員屬性在enemyPlane.h中添加如下代碼:#ifndef ENEMYPLANE_H#define ENEMYPLANE_H