为什么我要从Qt转向CEF

2,626 阅读4分钟

为何放弃 Qt ?

Qt 用了多年,非常顺手,说到放弃也是无奈之举,我先列举几条痛点。

高分辨率屏适配问题

Qt High DPI 的处理不尽人意。在高分辨率屏下开启缩放后,控件排版可能会变得混乱,导致界面变丑。需要写代码的同时消耗一定精力去做适配,这是一笔不小的开销。无法让人把精力更集中于业务开发上来。

我所使用的版本是:Qt5.15.2,它在4K屏下的表现,真的细节问题很多。我又安装了 Qt6.3.2 ,依旧存在很多表现不佳的地方。

平台兼容性问题

两方面顾虑:

  1. Qt6之后,已不再支持Win7系统,但现阶段还有一定量的Win7用户存在。
  2. Qt6之后,不再提供x86编译,但现阶段有一定量旧模块是x86编译的。

顺带看下Qt发布的几个跨度较大的版本说明:

Qt 版本Windows 版本要求说明
Qt 4.8.7Window XP经典的 Qt4 终结版本
Qt 5.6.3Window XP最后支持XP系统的LTS版
Qt 5.14.2Window 7最后一个提供二进制安装包的版本
Qt 5.15.2Window 7最后支持win7系统的免费版本
Qt 6Window 10不再提供x86编译,不再支持Win7系统

自定义标题栏问题

Qt 就没有好用的自定义标题栏方案,相信大家应该没有异议吧。每一种方案都或多或少有些不足,经常见到的有以下这些问题点:

  1. 模态框弹出后,鼠标点击其它位置,模态框失去了原有的边缘闪烁效果
  2. QMessageBox想自定义标题栏太费劲
  3. 窗体边缘没有阴影
  4. 窗体拖拽到最左侧或最右侧,没有操作系统自带的将屏幕二分展示功能
  5. 窗体拖拽到最上侧,没有最大化效果

要解决以上问题,我们需要自己写很多Native层代码,Qt本身并没有做出很好的支持。

综上,万般不舍但终是选择了放弃Qt!

为何选择 CEF ?

前面抛出的关于 Qt 的所有问题点在 CEF 中都不再是问题。那为何要选 CEF ,而不是其它框架?没有对比就没有伤害,接下来做个简单的对比。

传统界面库

先来看看 Windows 平台主流的 C++ 界面库有哪些:

Qt、Duilib、MFC、WTL、WindowsAPI

Qt 是目前非常主流的界面框架。Duilib 相比 Qt 来说,社区太冷清了,遇到BUG能找到的资料也很少。MFC/WTL已很少有人用了。WindowsAPI 可以直接放弃,对于产品开发来说,没有太多的实用价值。这些传统的界面库中,首推 Qt。

前端开发框架

先看看目前主流的前端开发框架有哪些:

Electron、CEF、Flutter

  1. Electron: 纯纯前端开发,基于 Node.js 和 Chromium
  2. CEF: 前端和 C++ 混合式编程,基于 Chromium
  3. Flutter: 谷歌推出的桌面应用开发框架,开发语言是dart

随着硬件性能的提升,传统界面库的表现力越来越比不过前端。如 Qt 的 QSS 样式表与前端的 CSS 比起来,也毫无优势可言。

短平快,是当下产品开发的主流旋律。前端在界面开发的效率上,是其它框架所不能匹敌的。当你还在忙着 paintEvent 自绘时,前端早已完工下班了。

要求低,传统界面库对研发人员的技术水平要求相对较高,而前端对于人员的技术水平要求,相对 C++ 来说要低一些。

统一性,传统界面库直接与操作系统API打交道,或多或少受到操作系统的影响,在不同系统下,界面可能长的不一样。而前端开发框架是运行于浏览器内核中,在排版风格上,不受系统影响,保持高度的统一性。

界面库对比

传统界面库,因其自身的复杂性,以及对研发人员的技术水平要求较高,不再考虑。

从 C++/Qt 程序员的角度出发,最合适的暂时只剩下 CEF 框架。

Electron 是纯前端开发,性能低是一方面,另一方面调用第三方,或是本地API没有那么友好。

Flutter 所使用语言 dart 对于 C++ 程序员来说,学习成本太高。

而 CEF 自身就是由 C/C++ 封装而来,可以直接调用所有的 C/C++ 接口,这是非常诱人的,意味着旧项目中的很多模块,都是可以拿过来直接用的,仅仅是把界面部分重构掉而已。

总结

CEF 解决了高分辨率屏适配问题;支持 Windows, Linux, Mac 平台;自定义标题栏很简单;可以直接与 C/C++ 打交道;由 Chromium 内核渲染界面,排版风格高度统一;