桌面软件开发框架盘点
2023-08-26 11:01:52 阿炯

互联网出现之前,C/S 架构是软件产品的主流,后面渐渐地被 B/S 架构所取代(因为不需要配置客户端),但由于浏览器有刷新机制,服务器的负载等因素,C/S 架构的响应速度和流畅性是好于 B/S 架构的,所以现在软件开发的趋势是两者的融合,一般是 B/S 架构开发的产品可以非常方便地转移到 C/S 架构下。

客户端(Client)是 C/S 架构软件产品中重要的一部分,除了和用户交互、本地处理数据的强大功能,顺畅的体验和美观的样式也是客户端技术追求的目标。在互联网时代,如何将一个好的理念快速的转化为产品,如何在原有产品中增加新的特性,是产品能够快速的推向市场、快速占领的关键。作为客户端的架构选型,面临以下几个方面的需求:开发速度快,能够快速迭代,快速试错客户端能够跨平台,同时适应Windows和Mac、Linux平台用户界面友好,满足用户对界面的苛求能够与快速与第三方的应用、Web应用集成客户端安装包大小适中,减少用户的下载和安装时间;支持旧有系统(国内还有近10%的用户是XP系统)、最大化利用公司现有的开发人员,减少因为技术选型引起的大规模人员变动。

GUI(Graphics User Interface),中文名称为图形用户界面,是指采用图形方式显示的计算机操作用户界面,是计算机与其使用者之间的对话接口,是计算机系统的重要组成部分。早期电脑向用户提供的是单调、枯燥、纯字符状态的“命令行界面(CLI)”,也有人称之为字符用户界面(CUI)。由于字符用户界面的操作方式需要用户死记硬背大量的命令,这对于普通用户而言非常不便。后来取而代之的是可以通过窗口、菜单、按键等方式来方便地进行操作。上世纪70年代,施乐公司 Xerox Palo Alto Research Center (PARC) 的研究人员开发了第一个 GUI 图形用户界面,开启了计算机图形界面的新纪元。这之后,操作系统的界面设计经历了众多变迁,OS/2、Macintosh、Windows、Linux、Mac OS、Symbian OS、Android、IOS各种操作系统将 GUI 设计带进新的时代。现在几乎可以在各个领域看到GUI的身影,如手机通讯移动产品、电脑操作平台、车载系统产品、智能家电产品、游戏产品等等。


施乐公司的第一个 GUI 图形用户界面


2023年上半年,笔者对目前的桌面软件开发框架进行了对比,总结了他人的一些经验心得,写下本文,希望对读者有所帮助。各个操作系统平台的桌面端可见《Linux桌面GUI开发介绍》、《Windows桌面GUI开发介绍》,《主流嵌入式GUI框架盘点》,Perl语言可参考《perl gui开发方案》。OsChina上也有《桌面应用程序开发框架》对目前部分的GUI开发框架进行了盘点,基于C++的老牌开发框架居多;泛Electron的Web Gui异军突起,其中Rust桌面框架在讯速增加,可参见《Web桌面GUI开发介绍》。


先盘点Windows桌面端(GUI)程序开发方案比较

桌面端开发建议使用以下技术组合:
Qt(C++) 性能高,效果好,跨平台,开发效率低(C++的问题?)。
WPF(C#) 性能适中,效果好,不跨平台,开发效率中等,占内存。
Electron(NodeJS) 性能低,效果好,跨平台,开发效率高,占内存,三方库支持少。

现在很多新应用都已经使用Electron来开发了,需要高性能的使用node-ffi调用原生即可。不建议使用Python+QT(或其他框架)来做客户端,在使用了一段时间放弃了:打包大,性能也不高,关键是相关的文档也少,出现问题找解决方案都难。如果性能要求不高的应用建议使用Electron,性能要求高点的用WPF或Qt(C++)。

Windows 下的 GUI 解决方案比较多:
基于 C++ 的有 Qt、MFC、WTL、wxWidgets、DirectUI、Htmlayout;
基于 C# 的有 Winform、WPF;
基于 Chromium和Node.js 的 Electron;
基于 Java 的有 AWT、Swing、SWT;
基于 Pascal 的有Delphi、Kylix(基于Qt)及其后的Lazarus
基于 Go 语言的有 walk;
还有国内初露头角而又停止维护的 aardio;
Visual Basic 曾经很流行,现在逐渐失去了色彩。

现在常用的方案

Duilib+CEF 只支持Windows的选择,优点是打包文件小(使用C++),成功案例有QQ、微信、有道精品课。
Qt+CEF 支持跨平台,缺点是打包文件大(使用C++)。
WPF/(WPF+CEFSharp) 打包文件小,但是性能相比前两者弱,但比Electron强,内存占用高,只支持Windows。
Electron 打包文件大,但是性能弱,内存占用高,支持跨平台。

几种方案都各有利弊,可以根据团队的情况选用,都是相对不错的;其他的方案比如Flutter,Java就不太推荐。

C++阵营

QT和Duilib区别

Duilib是一款windows的下界面库,采用skia自绘的方式完成控件的显示,目前是开源状态,类似的控件库还有soui。而Qt则不是界面库那么简单,还包含有数据库,web,com通讯,tcpip通讯等功能,应该称之为开发框架,并且包含了强大的ui系统。

Qt虽然开源,但是商业需要购买许可,Duilib则不需要。从稳定性上来说qt无疑是最为成熟和稳定的界面开发库,但是程序的运行依赖库较大,需要带上30~40M的qt基础库。界面实现效果上两则区别不大,都可以实现比较丰富的界面外观,但是duilib的文档和资源较少,对开发人员的要求比较高。此外如果涉及跨平台开发的话,duilib则无法胜任,其只能支持windows下界面开发。

Qt自带的控件样式比较简单,可以通过qss进行控件美化,但是效果比较简单,这里可以尝试使用qt-ui界面库进行样式扩展,实现更加丰富的界面效果。Qt-UI 是对Qt控件的一种扩展,支持所有原生qt控件的接口和文档,可以帮助Qt界面开发人员实现高质量的软件界面。常见的应用有如下:
Skype:一个使用人数众多的基于P2P的VOIP聊天软件
SMPlayer:跨平台多媒体播放器
Google地球(Google Earth):三维虚拟地图软件
Autodesk Maya, 3D建模和动画软件
VirtualBox:虚拟机软件
YY语音、咪咕音乐、WPS Office

用 Qt 来开发 Windows 桌面程序有以下优点:
简单易学:Qt 封装的很好,几行代码就可以开发出一个简单的客户端,不需要了解 Windows API。
资料丰富:资料丰富能够成倍降低学习成本,否则你只能去看源码,关于 DirectUI、Htmlayout、aardio 的资料就很少。
漂亮的界面:Qt 很容易做出漂亮的界面和炫酷的动画,而 MFC、WTL、wxWidgets 比较麻烦。
独立安装:Qt 程序最终会编译为本地代码,不需要其他库的支撑,而 Java 要安装虚拟机,C# 要安装 .NET Framework。
跨平台:如果你的程序需要运行在多个平台下,同时又希望降低开发成本,Qt 几乎是必备的。

微软自家阵营(Winform/WPF/UWP/WinUI)

微软家的技术就一个特点就是乱。一个又一个技术之出来之后双被推倒,导致每一个技术都不是特别成熟。


注意上图中
.NET桌面开发支持WinForm和WPF开发
通用Windoes平台开发支持UWP开发

请根据自身的需求选择安装。

Winform和WPF

WPF,即windows presentation foundation,windows呈现基础,属于.net framework 3.0,是微软推出取代Winform的产品,能做到分离界面设计人员与开发人员的工作,提供多媒体交互用户图形界面,三大核心程序集是presentationcore、presentationFramework、windowsBase。

WPF和Winform最大的区别在于WPF底层使用的DirectX,Winform底层使用的是GDI+,所以WPF的图形界面上更胜一筹。

GDI+(Graphics Device Interface)图形设备接口,它的主要任务是负责绘图程序之间的信息交换、处理,所有windows程序的图形输出。

DirectX(Direct Extension)多媒体编程接口,加强3D图形和声音效果,有很多API组成。

按照性质分类可分为四大部分:显示部分,声音部分,输入部分和网络部分。


WPF和UWP

Universal Windows Platform (UWP) 和 Windows Presentation Foundation (WPF) 是不相同的,虽然都可以做界面和桌面开发,但是 UWP 是一个新的 UI 框架,而且 UWP 是支持很多平台,至少比 WPF 多。

UWP要求系统为Win10

那么 UWP 可以使用什么写?
xaml 的 UI 和 C#、VB 写的后台
xaml 的 UI 和 C++ Native 写的后台
DirectX 的 UI 和 C++ Native 写的后台
JavaScript 和 HTML

那么网友说 UWP 的性能比 WPF 好?

因为 UWP 的渲染使用的是 DirectComposition 而 WPF 使用的 Desktop Window,虽然 WPF 渲染是通过 Dx9 但是最后显示出来是需要 Desktop Window Manager(DWM)。


WinUI

开发工具上默认是不能创建的,需要安装插件,不推荐。

该如何选择

WinForm和WPF之间肯定选择WPF,更灵活。

选择WPF还是UWP

WPF是基于多窗口的,UWP是基于但窗口多Page的,这就决定了两者的开发跳转思想是不一致的,UWP就好似移动端开发一样,页面的跳转是基于导航的,所以只要应用有多窗口的需求就不要考虑UWP了。如果应用只考虑支持Win10,并且所有的功能都能通过内部跳转,类似于WEB应用或手机应用的交互,那么用UWP才是理想的选择,启动快,占用内存小。

.NET Framework 和 .NET Core及.NET 5/6 对比
技术     是否跨平台     特点
.NET Framework     否     只支持Windows最新版本4.8,不再更新。
.NET Core     是     之前跨平台的方案,新建项目已经没有该选项,被.NET 5/6替代。微软推出吊开源社区胃口的产品,还是那句话:微软由之前对开源的敌视态度转为转变的五味杂阵,但从未真心过。
.NET 5/6     是     .NET Framework和.NET Core的替代品,在依赖都有的情况下推荐使用该方式。

Visual Studio 2022创建WPF的两种方式



这两种方式分别对应了
.NET Framework
.NET 5/6

已经不能选择.NET Core了。


桌面软件开发框架大赏


本节基于海康威视桌面端技术专家刘晓伦在「RTC Dev Meetup • 杭州站丨大前端时代的业务架构和跨端实践」活动中分享内容二次整理与补充。以下正文:今天与大家分享 19 款桌面软件开发框架,将它们分了四类,然后分别就每个类别做相应的介绍,希望通过今天的分享,帮助大家在桌面开发框架选型的过程当中少走一些弯路。

一、传统桌面软件开发框架

首先来聊一聊传统的桌面软件开发框架。这个类别中包含大家常见的 Qt、wxWidgets、GTK、FLTK、Swing 和 JavaFX。这六个框架有一些共同点:它们的历史都很悠久,使用的开发者也很多,并且相应的社区也很成熟,其中包含了丰富的资料。此外它们的功能都很强大,有大量成熟的案例,框架也很稳定。但是它们用到的都是相对来说都是比较成熟的技术,所以跟新兴技术之间还是有所差距,所以使用起来比较困难。

1、Qt

Qt 的优点大家都可以在官网上看到,这里不再赘述,其中有一点是 Qt 对各操作系统都做了很完善的封装,比如网络、文件剪切板等,如果要用系统级的 API,Qt 可以提供的非常丰富的 API。对于 Qt 的问题这里介绍一下我的感受,Qt 目前的问题是发展方向不太专一,无法提供某些较大的模块,在开发过程中可能会逐渐发现使用的模块不太合适,进而废弃这个模块,包括很多 API 也是这样,我之前用过的 Qt script 现在就已经被标记为废弃了。另外,Qt 的商业授权是不太友好的(这个授权问题已经持续了十数年,均不能得到很好的解决,反而更加恶化)。如果要开发一个商业应用,可能这里要注意一下,有很多国内的公司都是收到过 Qt 的律师函要求收费的。Qt 还提供了很多组件,其中有一些复杂的组件对于控制 UI 的细节是比较难的,这里就不再举例了。

Qt 还有很多的动态链接库,如果要做静态链接也是比较难的,当然社区中提供了一种办法,就是可以编译 Qt 的源码做静态链接,但是这就又要涉及版权的问题了。

Qt 近年来不太专一,qml,qtquick 等搞了很多,而且这些新玩意儿一直不温不火,有些模块做了又废弃了,比如:qt script,搞来搞去,搞的模块繁多且复杂,用起来不是很舒服。

Qt 有界面描述语言(XML 描述界面),可以通过设计器拖拽空间设计界面,编译期界面描述语言被转义成 C++ 代码,性能上没啥损失。

Qt 商业授权不太友好,开发商业应用一定要谨慎,之前听说有公司为此付出了高额的版权费。个人开发者可以免费使用。

Qt 的免费版本不允许静态链接,会有版权上的限制,但开发者还是可以通过一些特殊的编译方法静态连接 Qt 的库的。

除了使用 C++ 开发 Qt 应用外,开发者还可以使用其他语言开发 Qt 应用,最流行的就是使用 Python 基于 PyQt 做 Qt 应用了,其他语言的绑定不是很成熟,但 PyQt 仍然有版权的问题。

2、GTK

GTK 框架比较偏 Linux,在 Linux 中有很多桌面应用都是用 GTK 开发的,在 Windows 下 GTK 相对较少,并且在 Windows 系统下的静态链接也是比较难的,甚至搭环境都比在 Linux 系统下要难得多。另外 GTK 在 Windows 下也做了系统 API 的封装,但是在 Windows 下的封装比在 Linux 系统下的封装要少一些。也就是说,有些 API 在 Linux 下能用,而在 Windows 下是不能用的,这样的 API 不在少数。最后 GTK 的商业授权是非常友好的。

虽然它是一个跨平台桌面软件,但它似乎只在 Linux 操作系统领域流行,有非常多的 Linux 桌面软件都是基于 GTK 开发的。这也直接导致 GTK 的维护者很重视 Linux 领域的发展,而忽视 Windows 和 Mac 领域。

这个框架提供的很多 API 只在 Linux 下有,Windows 和 Mac 下没有。甚至在 Windows 下编译一下 GTK 的源码都要比 Linux 下难很多,且 GTK 的渲染引擎在 Windows 下性能表现也不如在 Linux 下好。它在 Windows 上也没办法静态连接,倒不是因为版权的问题,而是它依赖了 MSYS2 的一些库,这个库用于在 Windows 上模拟 Linux 环境,这也是为什么 GTK 在 Windows 上表现不佳的原因之一。

另外,由于 GTK 是 C 语言开发的,所以开发风格也很 C 语言化,外加面向对象的思维实现,这对于部分开发者来说可能觉得繁琐。

3、FLTK

FLTK 框架是 C++ 之父推荐使用的,是一个非常轻量的 GUI 框架,但是轻量意味着功能是不足的,其功能比较少,几乎不做系统 API 的封装,大部分都要开发人员自己用 C++ 编写。这样导致开发人员在每个平台上都要重新编写,比如要开放一个跨平台的图片应用,那么在 Windows 下调用一些系统级的 API 进行实现,在 Mac 下可能又要实现一遍。FLTK 的优点是它的产物很小,因此它编译出来的东西可以做到很小,而且性能也非常好(比前两个都好)。FLTK 的商业授权也很友好,可以支持静态链接。但是 FLTK 有一些不足,就是因为它是一个 GUI 框架,因此在绘制 GUI 组件这方面是不太好的。我在使用 FLTK 的时候发现,在其中做动画控制、组件叠加(这时用到就是绝对定位,就需要对组件的层级进行控制)都会遇到问题。另外在绘制圆角的时候,虽然 FLTK 提供了相关的功能,但是用户还要控制圆角的特殊大小、某一个圆角出现等,这些都要写非常复杂的代码。

它是 1998 年创建的跨平台开源 GUI 框架,历史悠久,商业授权友好,而且 C++ 之父也用它,非常轻量级且支持静态连接,一个简单的应用编译后只有 500K 左右,非常赞,有自己的自绘引擎,用的是 OpenGL;但它的重绘机制是按区域重绘的,如果组件 A 所在的区域上存在组件 B,那么 A 组件重绘时,会把 B 组件的给重绘掉,开发者必须自己写代码处理这种情况。想象一下,如果想实现一个 A 组件 fade out 的同时 B 组件 fade in 的效果,就会非常麻烦。

FLTK 提供的一些组件样式都比较刻板,绘图 API 也比较少,想实现一个漂亮一点的圆角按钮(它内置圆角按钮的圆角大小是不能改的),必须自己画,而且还得借助一些非常奇葩的手段才行。

它是 C++ 开发的,但 API 不够现代,用起来总体还算舒服的,有 Rust 绑定:fltk-rs。它提供了一些与界面无关的操作系统 API,但非常少,几乎可以忽略。

4、wxWidgets

wxWidgets 跟前面 3 个框架有所区别,它是基于操作系统的 API 来做桌面应用的,也就是说,在 Windows 下开发一个桌面应用时,看起来就像是传统的 Windows 桌面软件的风格,在 Mac 下则是 Mac 的风格,而前面三个都有自己的自绘引擎。

也就是说,在前面三个框架中做一个按钮,不管用什么样的绘制方式,在三个平台下表现都是一致的,但是 wxWidgets 在三个平台上都是按照三个平台自己的 API 来绘制这个按钮的。wxWidgets 提供了非常多的操作系统的 API,并且可以做到静态链接,但小问题比较多。

wxWidgets 是 1992 年英国的一个大学教授开创的跨平台 GUI 软件,也非常成熟稳定,商业授权非常友好。它没有自绘引擎,而是对不同平台下的界面 API 做了整合和封装,这样开发者在 Windows 下开发的软件看起来就是 Windows 窗口风格、Linux 开发的软件看起来就是 Linux 窗口风格,这对于某些软件来说,正是他们想要的,但要想搞一些花哨的特效就没那么容易了。它同样也提供了大量的系统相关的 API 供开发者使用。

它是 C++ 开发的,所以对 C++ 开发者非常友好,除此之外它还支持静态连接,也就是说开发个应用不用分发给用户一大堆 dll。有些小问题但总体来说还是非常稳的;除了开发的界面比较死板外,没啥大的问题。

5、Swing与JavaFX

它们是基于 Java 的技术栈来做桌面应用的,因为要依赖 JVM,所以系统 API 比较多,但性能会一般,这两个框架可能相对来说用得少一些。

6、Duilib

是2010年国内一个开发者开发的GUI开发框架,因为底层基于DirectUI开发,所以只支持Windows平台,不支持跨平台,开源协议友好,商用没有任何问题(需要附加Lincence文件),国内有很多大厂基于这个技术做桌面端应用,比如网易、腾讯、百度,这个框架是基于C++开发的。

但框架本身还有一些问题,比如对高分屏支持不佳、特殊控件绘制上也有一些小问题,除了界面相关的API外,几乎没有提供系统级的API,作者纯粹是用爱发电来开发这个框架,所以更新不是很及时。

相对来说网易基于Duilib开发的分支更完善一些:NIM_Duilib_Framework,添加了高分屏支持、多国语言、整合了多线程处理的支持,但环境搭建相对比较麻烦。如果开发者要用这个框架,一定要用develop分支下的代码,master分支下的代码问题很多,这个框架看上去也是作者一个人努力的成果。

7、Sciter

Sciter是2006年创建的跨平台闭源GUI框架,足够稳定,它商业授权不友好,但个人开发者可以随便用(只能用动态链接库),一旦公司规模超过3人,就得买版权了(也就有权静态连接了)。其内部封了一个浏览器核心,但对这个浏览器核心做了大量的精简,不像Electron和NW.js动辄上百兆的体积,它只要6M左右就够了。底层的绘制引擎我记得是谷歌的skia,开发者可以使用HTML、CSS、JS来创建界面,当然由于底层是一个阉割版的浏览器核心,这也意味着有些浏览器特性它是不支持的,比如CSS3的flex布局,它就不支持(但它提供了自己的flex布局实现方式)。

以前它使用自研的一个脚本语言(和JavaScript很像),自从集成了Fabrice Bellard大神的QuickJs之后,就全面支持JavaScript了。另外它还对一些特殊的场景做了内置的支持,比如渲染大列表。它使用C++开发,有Rust、Go、Python等语言的绑定,但都是社区提供的,质量堪忧。有很多知名厂商都用这个库做界面,比如360、teamviewer、赛门铁克等。

另一个库RmlUi和Sciter很像,可以看成Sciter的替代框架,但RmlUi这个项目有三届作者,一个一个的弃坑不知道新任作者会不会弃坑,目前还不是很成熟,比如正在尝试帮作者解决的CJK输入法的问题,目前还不推荐大家使用这个框架。

8、Tcl/Tk

Tk 工具包是最流行的 Tcl 扩展,在多种操作系统上提供图形用户界面。每个 GUI 由一个或多个框架(framework)组成,每个框架内含布局管理器。采用C语言编写并采用BSD协议授权。


9、IUP

IUP是一个提供了可移植的、可编写脚本的工具包,可为C、Lua语言等来构建图形用户界面。这允许对GUI应用程序可进行快速部署、零编译的原型设计和优化。IUP的目的是允许用户界面可不加修改的方式在不同的系统中运行,尤其是对C与Lua(IUPLua)有相当不错的支持,采用MIT协议授权。

10、JUCE

基于C++的跨平台应用程序框架类库,用于开发桌面和移动应用程序,首发于2004年;JUCE尤其用于其GUI和插件库。它具有GPLv3和商业许可证的双重许可,其核心使用ISC协议授权。

11、NAppGUI

使用C语言(ANSI C90)构建跨平台桌面应用程序的专业SDK。作者巧妙地在操作系统原生API之上构建的一个轻量级层,它允许创建可移植的程序,速度极快,体积很小,不需要任何外部依赖,在MIT协议下授权。

12、SDL

SDL是一个C语言开发的、用于游戏开发的跨平台库,它提供了一系列GUI组件。其最大特色是其卓越的跨平台性,支持多种操作系统和硬件平台,例如Windows、Linux、MacOS、iOS、Android等;另外还提供了丰富的API和示例代码,使得开发者容易上手。SDL支持各种常用的GUI控件,例如窗口、按钮、标签、文本控件等,同时还有多种布局管理器可供选择。此外还提供了丰富的多媒体支持,包括音频、视频、图片处理等,使得开发者可以轻松实现复杂的游戏界面。

13、FOX

轻量级的C++ GUI框架,虽内部使用UTF-8但对多语言支持较弱。使用LGPLv3协议授权。

14、AWTK

在上文的嵌入式GUI框架中有介绍,不过该项目近年已经突破了嵌入式而走向更广泛的跨平台GUI开发用途,做为国产开源框架软件也提供了更多语言的移植与丰富的参考文档,值得推荐。

15、SFML

使用C++开发的单和快速的多媒体窗口库,采用Zlib协议授权,并为近23种语言提供了绑定。



大家可以在这几个桌面软件框架当中依据自身的实际情况做选择。

二、新兴桌面软件开发框架

刚才说的一些框架可能用的技术比较陈旧,大家开发起来比较麻烦。新兴的框架,比如微软的 MAUI、谷歌的 Flutter Desktop 和 JetBrains 公司的 Compose Multiplatform,都是采用非常新的技术来做的,开发起来很容易,开发体验也非常好。但是因为这几个框架都比较新,基本上都是今年发布的正式版(最早是 Compose Multiplatform 发布的,然后依次是 Flutter Desktop 和 MAUI),所以社区相对来说不如前面几个框架成熟,资料和成功案例也相对来说少一些。

1、MAUI

MAUI 是用 XAML 是写界面和逻辑的,大家如果用 WPF 写过软件的话,应该会对这项技术很熟悉。MAUI 用 C# 编写业务逻辑,只兼容 Windows 操作系统和 Mac 操作系统。MAUI 在 Linux 下是社区提供的一套支持体系,可能会有一些问题。另外 MAUI 是依赖 .NET 框架的,API 比较多,并且支持移动端(这三个框架都是支持移动端的,新兴的开发框架都兼容移动端的开发)。

这是微软的跨平台 GUI 框架,不仅仅支持桌面端,还支持移动端,但官方并不支持 Linux 的桌面端,该框架至今还没发布稳定版。

它是.NET 平台下的 GUI 框架,有自绘引擎,对 C# 开发者很友好,界面依然是用 XAML 描述的,可能很多人一听到 XAML 就直接弃坑了。XAML 表现力确实弱一些,个人觉得 WPF 没火起来跟 XAML 有直接关系。当然这是我个人的观点,也是相对来说吧(比 HTML/CSS 弱)。很多人觉得 XAML 挺好,也很有道理的。无意与大家争论。使用这个框架开发桌面应用得封一个.NET 框架给用户,当然有了.NET 框架应用程序访问一般的系统级 API 也就不成问题了。


2、Flutter

Flutter Desktop 是使用 Dart 编写界面逻辑的,它的组件比较丰富,并且支持 Win10 操作系统(之前的操作系统就不太支持了),API 是比较少的,需要开发人员自己来写。

这是谷歌的跨平台开发框架,开源、免费、文档齐全、投入力度大且持久,同样也新的很,Windows 版本刚刚发稳定版,Mac 版本还没稳定。如果完全没搞过移动端的 flutter,想用这个框架开发桌面应用,那么意味着你要学的东西还挺多的。好在 dart 和 flutter 入门都不是很难,学习曲线比较平缓。

由于 flutter 在移动端积累了很多年,所以界面上的一些东西在桌面端都比较稳(skia 自绘引擎),与操作系统相关的东西还不成熟,生态也不太好,比如想订制一下窗口的标题栏,想访问一下注册表这类工作可能得自己想办法。

不过它有类似 FFI 的支持,跟 C/C++ 语言打交道很方便。开发者直接使用 Dart 语言描述界面,这会导致众多大括号嵌套在一起的问题,可能很多开发者不习惯。使用 flutter-desktop 开发的应用程序打包后体积还比较大。


3、Compose Multiplatform

Compose Multiplatform 依赖 JVM,是用 Kotlin 编写逻辑的界面和逻辑的,有消息说将来可能会推出 Kotlin/native*,这样就可以不用依赖 JVM 了,但是这可能还比较遥远的事情。它的组件也是比较丰富的,大家都知道 Java 社区中有很多框架、模块等都可以使用,并且也是支持应用端的。

它是 JetBrains 出品的跨平台 GUI 框架,也非常新,前段时间刚刚推出 1.0.0 版本,这个版本还不是很稳,至少比 Flutter Desktop 的第一个稳定版要差很多。几乎没什么人用。它的自绘引擎用的是 Google 的 skia,这个自绘引擎稳的很,Chrome 和 Flutter 都是用的它,所以绘制、渲染之类的工作不太会出问题。比 Java 生态圈里的 Swing 和 JavaFx 要好很多。

JetBrains 的东西自然对 Kotlin 开发者友好啦,Java 生态下的很多东西都能用,访问系统级 API 也没啥大问题,同样也得考虑封一个 JRE 给用户。


在这几类框架里中我推荐大家使用 Flutter Desktop,虽然它们都是新兴的框架,所以很难说哪一个将来会更受欢迎,但是根据它们的共同点(技术更现代化、更加易用、资料较少、社区不成熟、成功案例较少、用户较少、不稳定),还是推荐 Flutter Desktop。

三、基于浏览器的桌面软件开发框架

基于浏览器的桌面软件开发框架相对较多,比如 Electron、NW.js、CEF、Sciter、WebView2、webview 和 TAURI。其中使用 Electron 比较多,也已经非常成熟。它们的共同点是它们可以复用浏览器的技术,比如 html、JS 和 CSS 等一系列生态中的组件。除此之外,它们还可以做非常绚丽的界面,因为 Web 技术发展这么年,CSS、html 等在标记和控制界面特性方面的技术都已经非常成熟,不像刚才提到的 FLTK 要做叠加动画效果都非常困难,如果用这些技术做这些界面会非常从容。但这些框架的功能也是有强有弱。

1、ElectronNW.js

Electron 和 NW.js 这两个框架是非常相似的技术,它们都是把 Chromium 与 Node.js 集成到一起,让开发者可以只使用前端技术开发桌面应用。如果要访问系统的 API,就用 Node.js 提供的 API,当然也有一些特殊的 API,比方创建桌面图标、访问剪切板、控制窗口大小等,是 Electron 框架本身提供的,而不是 Node.js 提供的,也不是传统 HTML 系统提供的,是在其中做了一些附加的操作,当然 NW.js 也有。

Electron 的作者曾经在 NW.js 团队工作过(NW.js 项目贡献第二多的人就是 Electron 的作者),后来辗转到了 github 公司,于 2013 年在创建了 Electron这个开源免费的产品。由于 VSCode、slak 等国际型产品都选择了它,所以从者甚众,其生态和周边工具链也完善的多。虽然开发方式上有点蹩脚的地方(多进程架构及模块归属进程),但瑕不掩瑜。Electron 每创建一个窗口都会多一个进程,这使 Electron 创建窗口的效率不高(秒级),NW.js 有复用进程的机制,即使新窗口加载完全不同域的页面也不会创建新的进程(毫秒级)。这也是为什么很多基于 Electron 开发的应用都使用 Dom 模拟弹窗的原因。

NW.js 最早把 Chromium 和 Node 绑定到一起,用前端知识做界面,用 Node 技术访问操作系统,最早叫 node-webkit,于 2012 年创建。基于 MIT 开源,可以无忧使用。微信小程序开发工具好像是用 NW.js 开发的(几年前调研过)。作者是英特尔的员工,英特尔的一些工具也是用 NW.js 开发的。除了 Chromium 和 Node 的能力外,NW.js 自己也封装了一些系统级 API,类似托盘图标、剪切板、系统菜单这种,但数量明显比 Electron 要少。

NW.js 可以在多个窗口间共享同一个 Node.js 上下文,而且还可以通过配置让 Node 的上下文和 Dom 上下文混合,这给开发者带来了很多便利。心智负担减少很多。不像 Electron 要时刻想着进程间通信,哪些模块当前进程不能用这类问题。虽然起步早,但奈何没有杀手级应用,周边的生态和工具链没发展起来。用的人越来越少,维护的投入也不如 Electron 大,再加上 Chromium 更新非常频繁,导致 NW.js 的有些 API 也不是很稳,恶性循环加剧。

这两个框架的作者都有很深的渊源,这里就不细说了。个人觉得 NW.js 实现起来相对来说比较巧妙,对开发者比较友好,而 Electron 维护更给力,社区也很庞大。无论是浏览器相关的 API,还是系统级 API,Electron 提供的都比 NW.js 多。


2、CEFWebView2

CEF 和 WebView2 框架都是直接基于 Chromium 开发的。CEF 的历史比较悠久,而且更灵活,大家可以通过这个框架进行自由的控制,API 也更多。WebView2 是微软的短期团队提供的一个框架,这个框架也是直接基于基于 Chromium 做的封装,它提供了 .NET 和 C++ 的 API,大家可以用 .NET、C++ 或者 C#语言去操作这个框架,目前还不支持 MAC(将来可能会支持)。

CEF 是 2008 年创立的,基于 Chromium 的跨平台 GUI 框架,稳定且商业授权友好,国内很多大厂都用的 CEF:比如微信桌面端、网易云音乐桌面端(Win)、QQ 桌面端、微信桌面端、MATLAB、FoxMail、OBS Studio,装机量破亿(过于保守)。

由于它几乎封了一个完整的 Chromium,所以体积非常大,但它支持所有的 HTML\CSS\JS 特性,几乎不提供任何与操作系统相关的 API,创建个托盘图标、读写个文件啥的,都要开发者自己完成,用 C/C++ 开发完成的,对 C++ 用户非常友好,它有 go/python/java 等语言的绑定,但都是社区提供的,质量值得担忧。

它对 Chromium 封装的很好,避免了开发者直接与 Blink、V8、Chromium 等复杂的代码打交道,很多功能都有默认实现方式,遵从约定由于配置原则,有经验的 C++ 开发者可以很轻松的驾驭 CEF 框架。由于 Chromium 是版本弟,所以 CEF 版本发布也非常频繁,很多被标记为稳定的版本,还是会出一些莫名其妙的问题,选一个好的版本非常重要。与 Electron 一样,它也是分主进程和渲染进程的,所以开发者要非常娴熟的运用跨进程通信的技术,虽然 CEF 提供了跨进程相关的 API,但复杂度还是有点高的,使用的时候要认真细心。

WebView2是微软 Edge 浏览器团队推出的跨平台 GUI 引擎,是闭源的,目前只支持 Windows,对 C# 和 C++ 开发者友好,如果使用 C# 开发,就得考虑把.NET 运行时分发给用户,如果使用 C++ 开发,就得自己处理系统级 API 的操作,webview2 本身是不对系统级 API 做封装的。

这个框架推出有小段时间了,但很多 API 也还不稳定,更值得担忧的是这个团队,他们前不久刚刚放弃了自己的浏览器核心转而使用 Chromium 浏览器核心,不知道他们会不会放弃 webview2 这个框架。

其优势是可以复用系统当中已存在的 webview2 二进制资源,即它虽然封了一个 Chromium 浏览器核心,但如果可以确定客户电脑已经存在了基于 webview2 开发的应用,那么安装包体积可以足够小。它也是多进程架构,甚至比 Electron 还要多一个进程(为了复用二进制资源),资源占用比较多。


相对来说 CEF 更像作者个人在维护,WebView2 就更像一个团队,但是因为 WebView2 不开源,所以也没法参与。


3、webviewTAURI

webview 和 TAURI 使用操作系统内配置的浏览器核心,比如应该在 Windows 下部署,那么就用 WebView2;如果在 Mac 下部署,就用 WKWebView;如果在 Linux 下部署,就用 webkitgtk 来做渲染,因此这里可能就会有一些兼容性的问题。

在做前端的时候经常会碰到一些兼容性的问题,但是目前来看,因为它们都是比较现代的浏览器核心了,所以这个问题还没有这么明显。另外TAURI 是使⽤ Rust 开发的,如果要选择这个框架,可能还得熟悉 Rust 语言。

webview使用操作系统的浏览器引擎来达到减小安装包体积的问题,Mac 上使用 Cocoa/WebKit,Linux 上使用 gtk-webkit2,Windows 10 上使用 Edge(也就是上面提到的 webview2),它不支持 Win7 的。由于不同的 OS 会用不同的浏览器核心,所以开发者使用它开发跨平台应用时要考虑前端代码浏览器兼容的问题。

开源且免费(MIT)有 Go、Rust、Python 等语言的绑定,不过官方支持的是 Go 语言,C 和 C++,操作浏览器的 API 非常少,不支持自定义 scheme,更别提系统级 API 了。

TAURI采用的技术方案与 webview 类似,所以安装包也足够小,非常新,还没发布稳定版,开源免费。webview 框架碰到的问题 TAURI 都有,使用 Rust 开发,将来会支持 Deno,作者说将来会直接使用 webview 的技术来支持多平台,


4、Sciter

Sciter 是一个比较特殊的框架,这里把它单列出来(因为上文有涉及),其对浏览器做了很多的削减,可以把产物的体积缩减到 10M 以内,前面几种框架基本上只要把浏览器核心分发给用户,即使压缩过后也得 60M。Sciter 以前有一个自己的脚本叫 TIscript,现在用的是 QuickJS,它的功能非常强大,而且集成了 skia 的核心版本。我不知道大家有没有关注过一个叫作 rustdesk 的项目,之前它选择的就是 Sciter 框架,当然这个框架的小问题也会比较多。


如果大家选择这类框架,推荐使用 Electron/CEF 框架。如果团队中没有 C++ 开发人员,或者不易于使用 C++ 进行开发应用,就选择 Electron;如果有 C++ 开发人员,而且应用非常注重性能,就选择 CEF。


四、即时渲染桌面软件开发框架

即时渲染相对应用的是保持模式的桌面应用框架,一般做桌面应用都是哪里需要更新,就更新哪里,框架会进行渲染。但是即时渲染是不一样的,它是每刷新一帧,就会把显示的内容都更新一遍,也就是说每一帧都会全部更新一遍。所以这类框架有一个共同的特点,就是它们要消耗 CPU 和 GPU 资源,传统框架的配置都是保持模式,如果不更新是不会做渲染的。另外,这种框架与游戏应用可以无缝对接,但是传统应用案例比较少,小问题比较多,且尚在发展中。

1、ImGui

即时渲染桌面软件开发框架中,Dear ImGui 比较流行,最近作者在开发 Dock 模式,估计今年有可能会推出,到时候大家可以去尝试一下。它的开发方式是比较特别的,就是每个循环都在做渲染。比如使用 Dear ImGui 做事件开发时,会将某一个变量设置为 true 或者 false, 在这一轮渲染的过程当中是 true,在它下一轮渲染过程当中,我发现变成 false 了,我们就认为触发了某个事件。而不是像 web 开发领域中,当出现一个 event 时,另一个组件就可以接收到它。

该GUI框架的实现原理和开发方式可谓独树一帜:它在一个无限循环里不断的重绘整个界面,别的 GUI 框架都是哪里更新了重绘哪里,它是无论有没有更新,一股脑全部重绘,而且一直在重绘,这样做对于一些不支持 GPU 的客户端来说 CPU 消耗会略高一些,不过总起来说还算好。其对游戏开发者很友好,很多游戏都集成它来做用户交互(游戏内的一些设置界面、聊天界面之类的),它支持很多种绘制引擎比如 OpenGL,Directx,Vulkan 等;打包后体积很小,也就几百K 的样子,也有一些小问题,比如:要用很恼火的方法在界面内使用同一种字体的不同的字号。如果打算使用这个库,建议你不要选 master 分支,而选 docking 分支(这个分支下有很多 amazing 的特性)。


2、Nuklear

Nuklear 是使⽤ C 语⾔开发的,更贴近 C 开发者的习惯,⽤户相对 ImGui 更少、⼩问题更多。


3、RmIui

RmlUi 比较特殊,它不是即时渲染框架,但是却有即时渲染框架的通病,就是用它开发应用之后会持续消耗 CPU 和 GPU 资源,它可以使用 HTML 和 CSS 描述界面,上手相对比较难,开发非常灵活,界面也很灵活,资源消耗相对更多。

最近一直在用这个框架,也跟作者进行了深入的交流。这个框架开发出来的应用程序可以做到 2M 左右,它可以解析你的 HTML,做一些非常特殊的效果,比如阴影、渐变之类的动画,但是它很小,不像浏览器一样,即使压缩也得 60 多兆,这也是它的优势。


这几类框架中我个人推荐 RmlUi,如果到作者的项目中进行提问,他基本上隔天就会回复。

五、小结

在做小结之前先简述一下这几个框架的对比。其实我们在介绍传统的桌面开发框架的时候,Qt 和 wxWidgets 内置的组件也有基于浏览器的,就是 QWebEngin 和 wxWebView,QWebEngin 封装的是 Chromium 的核心,其实与 CEF 和 QWebEngin 挺像的,但是很多人在用 Qt 的时候,是把 CEF 集成到 Qt 中,反而不用 QWebEngin。他们坚持的观点就是 QWebEngin 还不成熟,性能力相对来较弱,不如 CEF,但是目前来看,我个人认为,在 Qt 6.2 和 Qt 6.3 之后,QWebEngin 的 API 会更多,应用的需求更容易满足。wxWebView 更像是 webview 和 TAURI,它也是在不同的操作系统上使用操作系统的浏览器核心,这里就不多说了。

再看一下 RmlUi 和 Sciter 的对比。RmlUi 可以用 html 和 CSS,Sciter 也可以用 html 和 CSS,因为 Sciter 集成了 QuickJS,所以它也可以写 JS 代码(但是也得写 C++,因为你不可能不用操作系统的 API,但是它的 C++可能会比 RmlUi 的 C++ 代码量要少很多)。两个框架都不支持全部的 html 和 CSS 规范。

如果要选一个桌面软件开发框架,应该确认侧重哪方面的能力,我认为有三方面的能力是需要注重的:
:比如布局、元素定位、圆角、阴影、渐变
:比如鼠标事件、键盘事件、触屏事件、媒体播放结束、网络状态变更等
:处理业务逻辑的时候,界面渲染工作不能暂停 另外,桌面软件开发框架各有各的优势,比如软件开发逻辑很复杂,而且要快速地完成,那么 BrowserCore 可能是一个不错的方式,因为用前端技术来编写速度更快,但是如果软件需要更少的资源消耗和更快的运行速度,那么就需要考虑 Native 方式。

这么多框架可以说各有特点,有的成熟稳定,有的运行高效,还有一些框架单凭业务表达能力取胜,开发者在做技术选型时往往会难以抉择。这里总结了三个判断桌面软件开发框架是否优秀的底层逻辑,这可以帮助开发者认清真相,做出最优选择。

第一,是否具备独立的界面描述语言(UI DSL)。

这非常重要,是一个框架表达业务的重要能力。类似 WPF 的 XAML、qt ui 文件里的 XML、HTML + CSS 都属于界面描述语言,这都属于一种通过特化的 XML 来描述界面的方式;还有一种通过代码来描述界面的方式,flutter、qml 和 Compose Multiplatform 都以类似这样的界面描述语言来描述界面的。如下伪代码是 Compose Multiplatform 的界面描述形式:
panel {
  row {
    checkBox(...)
    row {
      textField(...)
    }
  }
}

但无论如何,显而易见的是,没有任何一个界面描述语言能比得上 HTML + CSS 组合。想想看:HTML 里各种五花八门的语义化标签和 Dom 操作技巧、CSS 里的布局方式、伪元素、动画描述等,就会明白这一点。

第二,是否拥有强大的事件处理机制。

作为一个 GUI 应用,与用户的交互、与设备的交互必不可少,这就涉及到形形色色的事件,比如与设备有关的鼠标事件、键盘事件、触屏事件、网络状态变更事件等,与界面元素状态有关的界面加载完成事件、媒体播放结束事件、元素大小改变事件等。另外能接收这些事件还远远不够,还得处理事件冒泡、事件捕获、事件分发等等。我认为 JavaScirpt 与浏览器核心的结合来处理各种各样的事件也是表现出众;而且经历了数十年的发展,这套组合的事件系统也相当成熟稳定。

第三,是否拥有强大的异步、并行处理机制。

开发者不能在处理用户业务逻辑的时候,让界面渲染工作阻塞,这就需要一个强大的异步、并行处理机制,如果让开发者自己去创建线程并完成这些工作,无疑是又麻烦又会增加开发者的心智负担。

JavaScirpt 虽然是单线程执行的语言,但浏览器核心是多线程的(还是多进程的),所以其与浏览器核心结合后,开发者既不用为开发多线程应用而苦恼,又不用为没有多线程的支持而手足无措。


从以上三方面的技术需求来看,在桌面 GUI 应用里封装一个浏览器核心还是非常有价值的,这样开发者就可以用 HTML + CSS 强大的能力来描述界面,用 JavaScript 强大的事件处理机制和异步处理机制来完成用户交互。

Web相关的技术之所以胜出,并不是这些技术的设计者有多厉害,而是这20多年间,有大量的人涌入了这个领域,前赴后继的推动着它前进。其他任何一个领域都没有这么热火朝天的景象。用Web相关的技术做GUI应用的优势是,让开发者可以把大部分精力投注在业务本身上,而不是处理与GUI相关的技术细节。实际上所有的框架,都应该是这个目的,比如ORM框架,目的应该是让开发者把大部分精力投注在业务与数据之间的关系上,而不是管理关系型数据的技术细节。

当然这肯定是有损耗的,在性能、稳定性、资源消耗上,都会有所削减。且因为有框架的存在,开发者很难深入到框架内部做一些特殊的事情。比如该如何修改HTML的排版渲染机制呢?

所以有些框架注重性能,有些框架注重开发效率,开发者做选择题的时候也应该衡量这两个问题,你的应用对哪些方面要求多一些呢?

如果要开发一个视频监控系统,没多少业务功能,但要24小时不间断的记录视频数据,随时调取某一段时间的视频数据,这种应用可能Qt是最好的选择。如果要开发一个类似飞书的团队协作应用,业务逻辑复杂的一塌糊涂,而且要在短时间内满足更多用户的需求,占领更多的市场,那么Electron可能是更好的选择(目前飞书已经不再用Electron了,他们自己编译了Chromium核心,自己封了一个类似CEF的框架)。

目前微软、谷歌、JetBrains等公司都非常重视桌面端开发框架,也在推各自的框架产品,说明桌面应用领域并没有没落,反而应该更加受到重视。虽然移动端应用大行其道,但我认为,只有生活、社交、轻娱乐等方向上的应用在移动端有较好的发展。文档协作、大型游戏、开发工具、专业管控软件等应用还是在PC端发展的更好一些,毕竟PC端有更多样的输入输出设备、更广阔的显示和交互的空间,更强的存储和计算能力。

另外,要做桌面应用开发需要了解一些底层知识,比如多线程、多进程的控制;各种通信协议;⽇志收集;版本控制;设计模式与架构原则;本地数据控制;操作系统。

六、问答环节

1、用 Electron 怎么处理 Crash?

Electron 也有非常多问题,它也会崩溃,并且有崩溃报告的收集方式,收集这些报告之后还要进行分析,但是分析出来的崩溃报告实并不能很明确地反映到底是哪一行代码、哪一段业务出了问题。很多时候崩溃报告中可能更多的是说明一个指针指向的内存出现了问题,这时一种方法是尽量联系用户复现问题;第二种方式是做大量的自动化测试,收窄问题的范围,将其局限在一定的范围内再做精细化处理;第三种方式就是做 AB 测试。

2、Electron 开发的应用安装包太大这个问题有没有好的解决办法。另外开发者该如何开发 Electron 应用的守护进程。

这是两个问题。第一个问题就是包太大的问题,这个其实是挺难解决的,在立项之前就应该跟团队负责人沟通好需求,是要快速的业务开发,还是更高的性能,更小的体积?如果要更小的体积,那么就放弃业务开发效率。可以使用 C++ 做一些工作,只是会消耗更长的时间和更多的资源。在打包的时候,要先确认是否用的是 LZMA 压缩格式,这种格式可以压缩得更小一点,但是小不了多少,最低可能还是 60 多兆。至于怎么做守护进程,这个问题现在有两种办法,一种是写一个独立的应用,在 Electron 启动的时候应用就可以随之启动,然后它守护 Electron 进程。如果 Electron 进程崩溃的时候,就由它来启动 Electron 进程。

另一种方法是分析应用为什么崩溃,是主进程崩溃了,还是渲染的时候崩溃了,你如果主进程崩溃了,尽量还是要找到其崩溃的原因,因为一旦主进程崩溃,那么所有渲染都会失败;如果是渲染进程崩溃了,那么可以在主进程中打开一个其他的进程,来保证将渲染崩溃的通知发送给用户,由用户重启渲染进程,或者自动重启。


Electron相对于其他的跨平台技术,简单易上手(一力降十会),开发效率较高,别人有的功能,几乎他都有(原生操作系统能力除外),而且生态较为活跃。对于web端,可以实现一套代码,多处运行。缺点:系统资源占用较高,首先,在打包体积上,相对于Qt等,粗略估计体积要增大50%;其次,打开新窗口有明显的白屏时间,性能较差的电脑,白屏时间更加明显,这一点是企业级开发较为头疼的一件事,而且没有好的优化手段,每个窗口都会对应一个新的进程;最后,由于electron是套一个chromium壳子,虽然可以访问操作系统资源,但是能力有限,不如QT等功能全面。javascript的特性决定了前端项目模块化管理就是一个大问题,即使靠ts、npm、乾坤之类的工具或框架,也有一堆坑要填。所以,除了阿里华为那些不差人才的大公司。用electron,更适合一些简单的增删该查应用,一个版本的生命周期在一两年内;如果要做十年、二十年的企业应用,还是老老实实用qt或c#吧。

Flutter是一个由Google开发的跨平台应用开发框架,最初只用于移动端为Android、iOS开发应用。2022年5月,Google 在 Google I/O 2022 发布了 Flutter 3.0版本,宣布对 Windows、macOS、Linux 桌面操作系统提供支持。Flutter Desktop 是使用 Dart 编写界面逻辑的,Dart语言容易学习和上手、开发成本低。此外,Flutter的组件比较丰富,并且支持 Win 10 操作系统(之前的操作系统就不太支持了)。但因为桌面端才刚刚发布稳定版支持,生态和稳定性都有待考量,还有API 也是比较少的,需要开发人员自己来写。


七、快速回看

桌面应用程序又称为 GUI 程序,其发展可以分为以下几个阶段:

VB vs Delphi

C++、win32API 的 MFC 方案
基于窗口中组合控件和消息传递机制。这也是 20 多年前的技术,所以 API 设计的不是很友好。几年前微软已经停止维护,简单来说它已经过时了。

C# .net framework,代表就是 WPF
它的原生特性是其他类库无法比拟的:High DPI、Split Screen 以及对 DirectX 的天然优势。但是并不开源,需要依赖.net 框架,还有就是启动会比较慢。Workstation Windows 的新客户端就是基于该技术研发。

Java swing/javaFx
这是一类比较大的阵营,优势是跨平台和流行开发语言 Java 的天然结合,但开发出来的界面作者个人认为并不美观。

C++ Qt
这是很多客户端跨平台的首选,因为开源、UI 库和各种功能的类库非常丰富,但是学习成本比较高。

C++ duilib
这是 windows 下开源的 directUI(微软提出的分离 UI 和逻辑的思想)库,它是迎合互联网桌面软件小而美的趋势发展起来的,可能大家对它的关注度比较少。但是用它开发出的产品大名鼎鼎,比如 QQ、微信、爱奇艺等很多知名度高的软件。

Objective-c/swift cocoa
这是 mac 平台下的方案。可以方便调用底层的 API,缺点是不跨平台,文档不友好,UI 库并不丰富。现在这种方式开发的越来越少了。

基于 Web 技术的桌面应用开发

从 B/S 和 C/S 架构逐渐融合的角度来说,基于 Web 技术进行桌面程序的开发渐渐变成了主流,因为对界面的代码部分可以做到复用。

VB+webBrowser(基于 IE 内核)
这类技术早期的方案是用 vb 内嵌 webBrowser 控件,基于 IE 内核,正好很多网页开发也有用 activeX 的需求,但这种方式具有明显的缺陷——非常依赖于用户的环境,会因为组件缺失导致程序各种崩溃。

嵌入式网页框架
这类技术主要是基于浏览器引擎实现 UI 渲染。比较典型的就是 appkit 上面 UIWebView 和 CEF。这种方法可以使用网页 HTML5+CSS 实现各种酷炫的效果,但是缺点也比较明显,就是桌面程序里面嵌入了一个类似 Chrome 的浏览器,内存的开销会比较大。

nw.js 和 electron
后面出现了 nwjs 和 electron。相比 CEF,Electron 有了单独执行 js 的 v8 引擎:可以运行 NodeJS 来完成服务器端功能,通过和内部浏览器的 v8 引擎交互可以实现一个独立的客户端,这不同于 CEF 需要寄宿在其他程序内部。

目前来看 electron 不能算一个年轻的开源项目, 还有不少新的桌面替代技术在涌现(比如 miniblink)。