QT 和 MFC 的优缺点比较
(MFC 效率较高,但大量的 Windows API 和消息机制使得其较难理解,不易用;QT 封装较好,易用且==跨平台==,但效率较低)
MFC(微软基础类库)是专门为 windows 设计的一个用于开发图形用户界面的类库。MFC 或多或少使用了面向对象的方法包装了 Win32 的- API,正因如此,这些 API 有时是 C++,有时是 C,甚至是 C 和 C++的混合体。-
Qt 这个 C++的图形库由 Trolltech 在 1994 年左右开发。它可以运行在 Windows,Mac OS X, Unix,还有像 Sharp Zaurus 这类嵌入式系统中。Qt 是完全面向对象的。
Document/View model
MFC 编程需要使用 Document/View 模式以及模板(template),如果不使用的话,编程将变得异常困难。而且,模板(template) 设定了固定的结构,若所需结构乃模板未定义之结构,则编程难已。例如,划分一区域使显示两个视图(view)于两个文档(document)。还有一个经常的问题是:模板(template)创建了视图(view)却无法访问(access)它,文档(document)要做完所有事情,但是这经常会出现问题。Qt 不强制使用任何设计模式。如果你认为恰当,使用 Document/view 没有任何问题。不使用也没有任何问题。
伪对象 vs 真对象
归根结底,Qt 和 MFC 的差异在于其设计的差异。
MFC 的根本目的是访问包装起来的用 C 语言写的 windows 的 API。 这绝非好的面向对象的设计模式,在很多地方,你必须提供一个包含 15 个成员的 C 语言的 struct,但是其中只有一个与你所期望的相关,或者必须用旧式的参数来调用你的函数。
MFC 还有许多让人摸不着头脑的地方,函数名没有任何的连续性。比如,如果你创建了一个 graphical 类,直到调用了 creat()以后该类才会被创建。然而对 dialogs,必须要等到 OnInitDialog()才能创建这个对象。奇怪的是到了 views,创建该类的函数名竟然成了 OnInitUpdate(),......你自己创建一个类用他们的方式调用它,你的程序崩溃了。比如说有一个 dialog 包含 CEdit 控件,如果没有调用 DoModal()你就不能使用 GetWindowText()。否则将会莫名其妙的失败。总之,MFC 充满了丈二和尚摸不着头脑的事情,并且,这种错误很难调试。
Qt 恰恰相反,它的架构明显是经过精心设计的面向对象的。Qt 因此在命名,继承,类的组织等方面保持了优秀的一致性。你只需要提供唯一一个方法的参数,仅此一个。在不同的类中调用方式也是有很强的连贯性。返回值也很有逻辑性。所有一切达到了简单和强大的和谐统一。一旦你使用了其中一个类,其他的类也就触类旁通,因为他们是一致的。在 Qt 中可以利用 Edit 控件,用 C++创建类的方法来创建自己的 QLineEdit。永远可以马上访问任何的方法,不管它是显示还是隐藏。在这里没有迷局,一切都按照你认为的简单的方式来运作。消息循环
MFC 是事件驱动的架构。要执行任何操作,都必须是对特定的消息作出响应。Windows 对应用程序发送的信息数以千计,遗憾的是,要分清楚这些分繁芜杂的消息是很困难的,并且关于这方面的文档并不能很好的解决这些问题。Qt 的消息机制是建立在 SIGNAL()发送和 SLOT()接受的基础上的。这个机制是对象间建立联系的核心机制。利用 SIGNAL()可以传递任何的参数。他的功能非常的强大。可以直接大传递信号给 SLOT(),因此可以清楚的理解要发生的事情。一个类所发送的信号的数量通常非常的小(4 或者 5),并且文档也非常的齐全。这让你感觉到一切尽在掌握之中。SIGNAL/SLOT 机制类似于 Java 中 listener 机制,不过这种机制更加轻量级,功能更齐全。
创建界面
MFC 无法创建大小动态可变的子窗口,必须重新手动修改代码来改变窗口的位置(这恰好解释了为什么 windows 里的 dialog 是不可以改变的)这个问题在软件进行国际化翻译的时候更加严重,因为许多国家表达相同意思需要更长的词汇和句子,必须要对每个语言的版本重新修改自己的软件。在 Qt 中,任何东西都可以手动的敲出来,因为它很简单:为了得到一个 button,可以这样些 button = new PushButton( "buttonName", MyParentName );如果想在按下某个按钮以后想调用某断代码的执行,可以这样写:connect( button, SIGNAL( clicked() ), qApp, SLOT( action() ) );Qt 拥有非常简单而又不失强大的 layout 机制,以至于不使用它就是在浪费时间了。Qt 还提供了一个图形用户工具,Qt Designer,可以用来帮助建立用户界面。可以修改所使用的任何控件的属性。不用将他们放在严格的位置,可以通过 layout 完美的组织他们。这个工具所产生的代码我们是可以实际上阅读并且可以理解的。生成的代码单独放在一个文件里,在编程的同时,你可以随心所欲的多次重新生成用户界面。Qt Designer 可以让你完成许多在 MFC 中不可能完成的任务,比如用预先填好的生成 listview,在每个 tab 上用不同的 view 来使用 tab 控制。帮助文档用户选择图形开发环境的时候,帮助文档是否周全是左右其选择的重要因素。Visual 的开发环境的帮助文档 MSDN(这个还要单独掏钱购买)非常的庞大,有 10 个 CDROM 光盘。他包罗万象,涵盖广泛。但是难免有泥沙俱下,主题模糊,关键信息不突出的遗憾。其链接设计的也很糟糕,通过链接很难从一个类跳转到其父类或者子类以及相关的类。如果你搜索一个关键字,不管是 Visual C++, Visual J++, Visual Basic,只要包含这些关键字的信息统统的返回来。Qt 的文档设计的相当优秀。你可以到 doc.tolltech.com 上面一睹芳容。Qt 的文档完备且详细的覆盖了 Qt 的方方面面,竟然仅有 18M。每一个类和方法都被详尽描述,巨细靡遗,举例充实。通过 Trolltech 公司提供的链接或者是 Qt Assistant 工具,可以方便的从一个类或者方法跳转到其他的类。文档还包含了一个初学者教程和一些典型应用的例子。同时还提供了 FAQ 和邮件列表,方便通过 Internet 或者用户群来查阅。如果你购买了授权,在一天之内你将会得到 Trolltech 公司的技术支持。实际上,Qt 优秀的帮助文档使得寻求外部帮助的机会大大减少。Tolltech 公司的一个宗旨是:有如此优秀的 Qt 产品以及其帮助文档,技术支持是多余的。
Unicode
使用 MFC,如果要显示 unicode,在编译链接的时候必须用到特殊的参数(和改变可执行文件执行的入口),必须在每个 string 前面加上 T,将 char 修改成 TCHAR,每个字符串处理函数(strcpy(), strdup(), strcat()...... )都要改变成另外的函数名。更令人恼火的是支持 Unicode 的软件竟然不能和不支持 Unicode 的 DLL 一起工作。当使用外部 DLL 来开发的时候这是个很严重的问题,但是你毫无选择。使用 Qt,字符串用 QString 来处理,其本身是与生俱来的 Unicode.不需要改变什么东西。不要在编译/链接时候增添参数,不要修改代码,只需要使用 QString 就可以了。QSting 类功能强大,你可以广泛的使用它,并且不要担心 Unicode 问题。这使得转换为 Unicode 非常的方便。QSting 提供了转换为 char * 和 UTF8 的函数。显然,MFC 的 CString 的设计相比于 Qt 的 QString 设计有着巨大的不同。CString 以 char *为基础提供了很少的功能。它的优点是当需要 char *类型的时候,可以直接使用 CString 类型。乍看起来这个好像是个优点,其实实质上还是有很大的缺陷的,特别是可以直接修改 char * 而不要更新类。在转变为 Unicode 的时候这个也碰到很大的麻烦。相反,QString 在内部以 unicode 存储 string,需要时提供 char *功能。实际上很少用到 char *,因为整个 Qt 的 API 用文本的方式响应 QString 参数。QString 还附带许多其他的功能,比如自动分享 QString 的内容。这是一个非常强大的类,你会喜欢在很多地方用它的。
国际化
使用 MFC 是可以国际化的,但是需要将每一个字符串放在一个字符串表中,在代码中到处使用 LoadString(IDENTIFIET)。然后转化这些资源到 DLL 中,翻译字符串到所需要的语言,改变图形界面,然后调用程序使用这个 DLL。整个过程是如此的繁琐,可谓牵一发而动全身。考虑的事情要面面俱到。使用 Qt 的时候,只需要将字符串置于函数 tr()中,在程序开发中这算是举手之劳。可以直接在代码中改变字符串的参考。Qt Linguist,Qt 的一个工具,能够提取所有待翻译的 string 并按照友好的界面显示出来。这个用户界面非常适合翻译,使用字典,显示字符串内容,恰当的 unicode 显示,快捷方式冲突检测,检测未翻译的字符串,检测字符串修改情况,功能齐全。这个软件可以供没有任何编程经验的翻译者使用。同时该软件在 GPL 的版权下发布,可以按照你的需求来修改它。翻译以后的文档保存在 XML 中,适合软件复用的原则。为软件增加一种新的语言版本仅仅是用 Qt Linguist 产生一个新的文件而已。
resources 问题
使用 MFC,一部分开发过程要依靠“resources”,在很多的案例中开发者必须使用他们。这样会导致如下的后果:出了 Visual Studio,你很难使用其他的工具来完成开发。资源编辑器仅有有限的功能,比如:通过 Dialog 编辑器不可能改变所有的属性,一些属性可以改变,另一些属性则不可能改变。(译者注:下面还有两条陈述 MFC 缺点的实例,但我感觉这些已经够说明问题了,暂时删节不译)然而 Qt 并没有资源的概念,这就解决了以上所提到的问题。Qt 提供了一个脚本使得能将编入你的代码。对于界面设计,Qt Designer 则创建了可读的代码。
价格
一旦你购买了 Visual Studio,你将免费的获得 MFC SDK。Qt 在 Unix 上是可以免费获得其遵守 GPL 版权的版本(译者注:现在在 windows 上也可以免费获得其 GPL 版本)。如果要开发不公开源代码的软件,必须购买 Qt 的授权。在特定平台下,每个开发者购买一个永久性授权,并获得一年的技术支持。(译者注:后面关于购买价格等问题删去,因为价格不固定,如果有疑问请到官方网站查询价格)
发布
在发布基于 MFC 的软件时,必须依靠存在于客户电脑上的 MFC。但是这是不安全的,同样是 MFC42.dll,可以基于相同的库得到 3 个不同的版本。通常,需要检查是否拥有正确的 MFC42.dll 版本,如果不是,就升级它。但是升级 MFC42.dll 会改变很多软件的行为。这让我感到很不舒服,如果用户在安装我的软件以后导致其机器死机该怎么办?Qt 则没有这个风险,因为 Qt 压根就没有“升级整个系统”这个概念。感觉 MFC 相比 QT 的确有很多的不足,但 MFC 的用户群巨大。Qt 要想短时间撼动 MFC 的地位,还是有点难度的
版权声明: 本文为 InfoQ 作者【乌龟哥哥】的原创文章。
原文链接:【http://xie.infoq.cn/article/191f81248d555618d92465732】。文章转载请联系作者。
评论