qt和c#怎么选_【选择】MFC,QT与WinForm,WPF简介
编程语⾔的组成
编程语⾔做为⼀种语⾔⾃然和英语这些⾃然语⾔有类似的地⽅.学英语时我们知道要先记26个字母,然后单词及其发⾳,接下来就是词组,句⼦.反正简单的说就是记单词,熟悉词法,句法.接下来就是应⽤了,听说读写.⽽使⽤相同语⾔的⼈⼤脑⾥都有个翻译器,可以把⾃⼰的想法翻译成语⾔然后⽤说或写表达出来,⽽听和读则把接收来的语⾔翻译成⾃⼰⼤脑能理解的思想.
那编程语⾔⾸先也是像英语⼀样会制定⼀些单词,然后词法,句法.像int ,char这样的类型关键字,或其他⼀些关键字就是单词.但这样的语⾔机器不认识的.所以就要个编译器来翻译成电脑能认识的01串.编译器就像⼤脑中的翻译器了.所以简单的说起来,⼀些语法规则加⼀个编译器就可以标志⼀门新的编程语⾔产⽣了.但语⾔内置的的都是些⾮常基本的操作,你要实现个啥复杂点的功能得写很多很多代码,于是有些⼈就先把很多常⽤的操作写好代码放那,你以后只管去调⽤.造好了很多轮⼦等着你⽤就⾏.这就是开发⼀些库(library)让你调⽤.在⾯向对象的语⾔中⼀般就叫类库,就是⼀堆堆的类嘛.如果类库⾜够强⼤,我们也可以叫作框架.反正我们可以简单的把框架理解为⼀些功能强⼤并且联系紧密的类库.
MFC和QT是C++中常见的GUI框架,⽽WinForm和WPF是C#中常⽤的框架,不过我们⼀般很少叫WinForm框架,可能直接叫图形控件类库更多点.反正只是个称呼罢了,爱咋叫就咋叫.另外WinForm与WPF(即Win
dows Form与Windows Presentation Foundation,⽤于windows 的上的桌⾯应⽤开发)都只是提供了⼀堆GUI类库,⽽MFC与QT除了⼀堆GUI类库外还提供了其他很多类.功能更强⼤.
GUI的重要性
GUI即graphical user interface(图形⽤户界⾯).可能很多⼈觉得整那些页⾯是个没啥技术含量的活.但实际上很多时候⽤户可不知道你后台代码咋写,也不管你咋写.他们看到的只有UI,觉得页⾯看着舒服,⽤起来性能不是太差,⽤个专业点的词说就是⽤户体验很好,那这就是个好软件产品.像苹果公司的产品这么受欢迎其中很重要的⼀个原因就是UI做的漂亮,让⼈觉得很酷.我们开发⼀个软件产品时,如果站在开发者的⾓度(站其他⾓度可能不⼀样)⼀个软件⽆⾮就是保存数据,处理数据,数据间⼀些逻辑操作,然后通过⼀个好友的UI界⾯与⽤户交互(当然有少数后台软件是不需要UI界⾯的).
我们知道各种设计模式是满天飞,五花⼋门,但知名度最⾼的是MVC模式(model , view,controller).就很好的体现了这⼀点,model + controller是数据处理那⼀块,⽽view就是UI界⾯.实际上QT,MFC,WinForm,WPF都相当于简化的MVC模式,由三层变成两层.model
+controller没做区分,弄成⼀层了.⽽view这⼀层则是单独弄出来,UI与与数据的逻辑处理代码的分离使得条理清晰,便于理解与维护.⽽且更重要的是很多UI控件都是做好了的,你直接拖来⽤不⾏.
另外你可能可能听说过STL(standard template library),标准模板库相当于把数据结构及对数据的操作(算法)这些常⽤的东东都做好给你调⽤,相当于把数据结构和算法那些思想实现成通⽤的代码供你调⽤.
为啥把这四个框架放⼀起来说呢,因为四者之前有类似的地⽅.相同语⾔之间的框架有相似那是毫⽆疑问,但实际上不同语⾔之间的类库也有类似的地⽅了.C++中的MFC和C#中的WinForm有点类似,⽽C++中的QT与C#中的WPF⼜有点类似
MFC与WinForm
view ui框架前⾯讲了这四个框架都是简化的两层的MVC模式.MFC中数据的逻辑处理⾃然是放后缀为h,cpp的这些⽂件中.⽽页⾯相关的那⼀堆东东放资源⽂件rc后缀的⽂件中.⼀般是⼀个project对应⼀个rc⽂件,但也可以多个project共⽤⼀个rc⽂件.当然在VS这开发环境中不会因为所有信息放rc⽂件中就所有页⾯控件堆⼀起了.在Resource View可以看到⼀个个分开的Dialog,每个Dialog就是⼀个页⾯,⾥⾯装着button等⼀些控件.当然资源⽂件还可以放其他资源的⽐如String Table,Bitmap之类的.如果你查看rc⽂件⾥的code,都是⼀堆begin 和end包起来的乱七⼋糟的东东.内容⾃然是控件的⼀些属性.code语法跟c++标准语法没半⽑钱关系.也不知道是按啥语法组织的.
分开了UI层,如果那些处理数据逻辑的代码要与UI交互就靠资源ID去关联.⽐如很多类可以共⽤⼀个Dialog页⾯,当然了很多时候我们⼀般是⼀个class对应⼀个dialog的.MFC中UI页⾯与后台代码交互起来
很不⽅便.⽐如要让某个控件(button,combobox之类的)与某个变量对应起来还得在DoDataExchange那函数⾥⾯写点代码关联起来.如果要点button要对应啥操作还得通过begin_message_map这样的宏来关联下.把某个控件送出的消息与⼀个函数对应起来的.当然了因为所有控件都继承⾃CWnd这类,所以也可以通过这类的⼀些函数去直接操作控件,⽐如GetDlgItem这样的函数,传资源ID做参数就⾏.
WinForm中也遗留了MFC⼀些思想,⽐如还有类似资源⽂件的东东,像sx⽂件,⾥⾯⼀般是放图⽚信息,然后Setting.settings就类似MFC⾥的string table.只不过这些功能在C#中⽤的很少.那些页⾯控件也不再是放资源⽂件中.WinForm中⼀切皆使⽤⾯向对象,数据逻辑处理代码与UI代码都是在同⼀个类中,只不过C#有分部类的概念,就是说同⼀个类的代码可以分开在⼏个⽂件中.假如有窗⼝类FormArwen,则数据逻辑代码放在FormArwen.cs⽂件中,UI代码放FormArwen.Designer.cs⽂件中.只不过这两个⽂件中类的定义都要写在partial class FormArwen 其中关键字partial是C#中独有的关键字,⽤来表⽰分部类,⼀个类可以在多个⽂件中定义.这⾥的UI代码也完全是标准的C#代码,不像MFC资源⽂件缺乏可读性.⽽且你完全可以把UI代码拷贝到数据逻辑代码中,放⼀起也完全没问题.
窗⼝中每⼀个控件都有⼀个name,相当于mfc中的资源ID吧,然后你在代码中调⽤控件时直接⽤这个名字就⾏,就相当于⼀个变量名字.所以代码与UI交互起来⾮常⽅便,另外MFC中的消息机制在这⾥被封装成了事件(event),你选中任意⼀个控件然后在它的propterties 的event页⾯中选择任意⼀个事件点击下就会⾃动⽣成⼀个类,你往类中直接写要处理的事件代码就⾏.这实际上就是把win32 API中复杂的消息
机制简化为⼀个event,⽤户⽤起来很⽅便,也不⽤管背后的复杂逻辑.MFC虽然对消息机制做了些封装,但封装的还不够好.
所以WinForm相对MFC⽽⾔,UI代码与数据逻辑处理代码交互更简单,更条理清晰,易于理解.背后⼀些复杂的细节都封装了不⽤⽤户管了.⽽且UI控件是功能更强⼤,看起来更漂亮啊.
QT与WPF
同为C++的GUI框架,QT与MFC不那么相似,那种逻辑反⽽更接近C#的wpf框架⼀点.⾸先不是所有UI相关代码都像MFC⼀样整到⼀个rc⽂件,⽽是⼀个UI页⾯有对应⼀个后缀为ui的的xml⽂件.⽽数据逻辑处理代码是放h,cpp⽂件中.⽽且这三个谁的名字都相同. ⽽如果要与控件交互也跟wpf⼀样⽅便,每个控件有个objectName,相当于MFC的资源ID号,然后调⽤控件时直接⽤这个名字就⾏,当然前⾯要加个指向⾃⾝所在类的指针.⽐如有类Arwen,有button名为btn,则⼀般是先Arwen* ui; 然后ui->btn就⾏.实际上跟wpf中⽤this.btn⼀样,只不过wpf中this前缀是可以省略的. 另外QT⾥⾯也没有MFC中的消息处理概念,⽽是封装成⼀个叫signal / slot的机制.这跟C#中的WinForm事件(event)⾮常类似,例如你右击QT中的⼀个按钮,然后右击go to slot选择⼀种signal,就相当于C#⾥⾯的各种类型的事件,当然signal的各类要少点.然后slot就是事件对应的处理函数.
WPF也是⼀个UI页⾯对应⼀个⽂件,后缀为xaml的⽂件,xaml全称是eXtensible Application Markup Lan
guage我们可以把它看成⼀种特殊的xml⽂件.⽽QT⾥⾯的ui⽂件就是标准的xml⽂件了啊.然后其他UI⽆关的代码就放xaml.cs⽂件中.
应该说从符合我们思维习惯的⾓度来说WinForm是最容易理解的,UI页⾯对应的代码完全是标准C#代码. ⽽MFC页⾯对应的rc⽂件,QT页⾯对应的xml⽂件,WPF页⾯对应的xaml⽂件都不是标准的C++或C#代码.不太符合我们的思维习惯.
知乎⼤⽜的介绍
WTL都算不上什么Framework,就是利⽤泛型特性对Win API做了层封装,设计思路也没摆脱MFC的影响,实际上⽤泛型做UI Framework也只能算是⼀次⾏为艺术,这个思路下继续发展就会变得没法⽤了,⽐如 代码过于复杂,编译太慢,出错不好调试等问题难以解决。
⽽且封装得也不完全,还是随处可见 HWND HDC之类的东西。
⽤途主要是写⼀些很⼩的程序,或者作为其他UI框架的后端实现部分,⽐如我写过⼀个⼩框架⽤来做安装卸载程序,⾮常⼩,其中创建管理窗⼝部分是⽤WTL的。MFC是更⾼级点的Win API封装,⽐WTL封装彻底,很难见到HWND HDC了,也提供了不少实⽤⼯具类,⽐如⾼级控件,泛型容器,IO访问,⽹络协议等。除此之外,还提供了⼀些基本框架,⽐如 Document/View,这就是个MVC的简化版本,只
有MV,但是对于数据的管理,消息的传递等⼜没有什么约束,导致Doc/View被⽤得乱七⼋糟。尤其是对事件处理的模型,消息映射是功能简陋,⽽且容易出错的⽅式,唯⼀优点是性能好。 从VC++ 1.X就有MFC了,那时整个UI界的设计思想都⽐较落后(除了Apple),MFC⼜背负了沉重的兼容性包袱,⽐如vc++ 1.52的MFC程序到了vc2003稍加修改都可以编译,导致MFC后期没有什么发展,就是沿着⽼的思路完善了些细节,添加了些组件,但是根本性的设计问题没有改进。GTK,这个吃了语⾔的亏,⽤C写⾯向对象实在是痛苦,虽然在思想上⽐MFC要先进了些,但是写出来的代码⽐MFC要罗嗦很多了。相⽐MFC,多了Layout的概念,事件处理上有了Signal/slot,虽然⽤起来很⿇烦。wxWidgets,这个基本就是个跨平台的MFC,对各个平台的差异做了抽象,实际上后端⼤多还是⽤平台原⽣的API实现,好多控件都是直接⽤系统原⽣的。有wxWidgets for GTK+的版本,后端就是GTK+,wxWidgets就是⼀层壳。这也是wxWidgets的优点,它编译出来的程序发⾏包⽐较⼩,性能也不错。以上这些就是上世纪90年代的UI Framework技术⽔平了,⾄今它们也依然没有太多进步。
下⾯来谈谈21世纪的技术。
Qt,虽然它也是上世纪90年代出现的,但是它在21世纪有了长⾜的进步。应该说它的起点就⽐较⾼,⼀开始就定位跨平台,⽽且不满⾜于简单封装系统API,⽽是要⾃⼰创造出⼀套完整的API和框架,甚⾄要代替系统API,所以不仅仅是做UI,⽽是涉及到了APP开发所⽤到的所有东西,包括⽹络,数据库,多媒体,脚本引擎等。signal/slot是Qt发明的,这是事件通知模型⾥C++语⾔的最佳实现了,甚⾄我都觉得
这该写进C++标准,估计C++委员会的⽼顽固们是从不写GUI的。
早期的QT也是没有DirectUI的概念的,每⼀个QWidget都对应⼀个原⽣窗⼝,从Qt4.4开始,只有顶层QWidget才是原⽣窗⼝,⽽Child Widget是Alien Widget,只是个抽象的图层不对应原⽣窗⼝,这就实现了DirectUI的概念,很多图形效果也就变得可能了,⽐如窗⼝层叠透明效果。
在4.8后实现了QPA(Qt Platform Abstraction),这就使移植Qt变得很容易,⽬前Qt是⽀持平台最多的框架没有之⼀。
由于早期授权的问题,Qt对于开源社区不是很友好,导致推⼴不太顺利,直到它改成了LGPL⽅式,如果Qt能早点想开了,恐怕就没有wxWidgets的⽣存空间了。
Qt的缺点也是有的,就是太⼤,不过可以⾃⼰剪裁,我可以把QT库剪裁到发⾏包压缩后2.5MB。
WPF,微软在Win Form的思路上⾛到死胡同后,终于痛下决⼼⽤正确的⽅法开发UI库了。21世纪的UI⼀定是定义出来的,绝对不能是代码写出来的,所以有了XAML这个强⼤的定义⼯具,不但可以定义UI布局,还包括图形动画效果,消息响应⽅式等。配合C#这种优秀的语⾔,更是如虎添翼。但是问题也很明显,就是过于庞⼤,不仅开发时要⽤到庞⼤的IDE和设计⼯具,发⾏的安装包也⼗分巨⼤,所以⽬前还是很少有⼈拿他写通⽤软件客户端的,⼤多是做企业项⽬时写专⽤客户端。
⼤概4-5年前吧疼讯曾经⽤WPF写了个QQ,但是只实现了基本功能就已经⽐C++客户端⼤好多了,⽽且运⾏缓慢,主要是太吃内存,⽽且那时WPF的优化还不充分。
最后我想补充下真正的UI库之王,cocoa。
Apple的成功有很多原因,其中之⼀就是cocoa,cocoa理念⼗分先进,⽽且出来得早,我都怀疑Qt和WPF有不少思想都是借鉴cocoa的。
定义式的UI,⽤xib就可以定义UI的绝⼤部分细节,⽽且提供所见即所得的可视化设计⼯具。
严格的MVC,⽽且定义⾮常清晰,分⼯明确。
signal/slot,虽然不叫这个名字,但思想就是,⽽且真的是拖动⿏标就能connect。
提供了ARC,闭包和反射,给UI开发带来巨⼤的便利性,当然这得益于Objective-C这个语⾔。
再补充下 Borland的OWL和VCL。
我是从Borland C++3.0和Delphi 1.0开始⽤的,那时的Borland看来很有前途的,可惜后来⼀系列决策失误导致现在这个公司⼏乎消失了,同学们不要再往这个坑⾥跳了。
OWL曾经和MFC是竞争对⼿,设计思想也差不多,个⼈感觉OWL的API设计更优雅⼀点,但是在市场上OWL被MFC彻底击败。
Delphi是神作,它在RAD(快速应⽤开发)领域长时间没有对⼿,直到BS架构取代CS架构。Delphi的特点就是简单、开发快,单纯就写个基本可⽤的应⽤来说,可能⾄今都没有⽐他更快的,但是缺点就是丑,基本⼤多数Delphi应⽤都是⼀⼤堆控件堆积在⼀起,很不美观,另外由于Pascal语⾔的限制⽆法和现有⼤量的C/C++代码融合。虽然后来有C++ Builder,但是Builder⾥简单和快的优点也消失了。Borland的C++编译器越做越差,导致后来开源项⽬都不太愿意兼容这个编译器了。
VCL准确地说不是UI库,⽽是⼀套组件接⼝规范,类似COM ActiveX。delphi和C++builder都是基于这个规范构建了基础库。
UI库是个很⼤的话题,够写好⼏本书来探讨的,我这⾥就是随便写点⾃⼰的感受。
单纯讨论每个库的优劣是没有意义的,⽽是要放到具体的应⽤场景⾥来看,每个库都有⾃⼰擅长的场景。
如果仅在Windows下,追求程序⼩巧,⽤WTL,不⾜的地⽅⾃⼰实现去吧,但是视觉效果就呵呵了。
如果可以⼤⼀点,还要好看点,那就Qt。
如果完全不在乎⼤⼩,只要视觉效果华丽,就⽤WPF,如果把开发⼯具价格也考虑进来,那么⼟豪才会选WPF呢。
MFC就是个鸡肋了,除⾮你现有的⼯程师不会⽤别的,或者有历史遗留代码要保持兼容。
如果要求跨平台,那么就⽤Qt,wxWidgets和GTK+跟现在的Qt⽐起来没有什么优势了。
如果是iOS Android,那么最好⽤原⽣UI库,除⾮你写游戏。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论