跨平台GUI方案
这个不甚平凡的暑假,小伙伴们有各自的事情要忙。在家实在闲不住,决定学点新东西,就像以往的假期那样。
这回打算学一下桌面GUI开发,想找一个现代化、高效又美观、最好能跨平台的技术学一学。简单调研了一下,当前的跨平台的方案有:
- Qt/Qt Quick
- Java SWT/Java Swing
- Electron
- python圈的,如pyQt
一直觉得Qt系列不温不火的,Qt Quick应该是它的发展方向。 Java的据说比较难写,外观不好处理。 Electron的代表作应当是vs code,前段时间发现的HexoEditor也让我印象深刻,界面很好看,毕竟是用前端技术写出来的。 python圈的似乎比较冷门,pyOt也算Qt,其他的一般都用来写“能用就行”的小东西吧。 此外,直接写个web端也是简单方便的选择。(比如Apache的很多项目)
总体看来,目前不存在很好的跨平台GUI方案,我能想到原因有:
- 平台间的差异必然的,每种系统都发展着自己的特性。作为最难跨平台的部分之一,GUI代码如果大部分能跨平台,操作系统的生态会受到很大冲击,这是一些系统厂商不愿看到的。
- 平台特性不同,GUI框架很难对同一份代码适配不同平台上的特性,让编程者自行分别适配也不是好方案,导致GUI框架支持的是各个系统特性的交集,往往比不上用平台工具开发的界面。
- web开发、移动开发是热点,桌面开发已经渐凉,跨平台的桌面开发就更凉了。
所以目前需要跨平台的大工程一般是分别在不同平台上实现界面。其实作为用户,我也更喜欢这样的软件。用跨平台框架写的软件往往体验更差一些,不能很好的利用平台特性,来优化外观、功能、性能等方面。
上面的方案虽然我基本上接触过,但只是皮毛,就不乱说了,这次的重点是electron。
我选择electron是因为它是开发方便、界面美观的新技术(相对其他方案),而且也能接触一下node.js。
node.js感受
node.js是一个js运行环境,相比传统js,它具有模块管理功能,提供了一系列内置模块,用来进行文件I/O、网络操作等等。
它的语法与js没什么区别,思想也是单线程、事件驱动的。目前主要由于写服务端应用。
Electron感受
一个electron项目基本上是把chrome内核和前端页面打包在一起,其中的的js用的是node.js,而执行js和进行网页渲染的是electron。换句话说,electron是把网页包装成桌面应用的程序。
electron应用的入口是主进程脚本,语言是node.js,它在后台运行,可以调用api创建新窗口,进行窗口管理等。
新窗口在新进程中运行,叫渲染进程,也许是因为它有网页渲染器吧。渲染进程的起点是一个html网页文件,不同之处在于,其中的js是node.js,并可以调用electron的一些api。
基本上,渲染进程执行的代码构成了View层,主进程脚本负责控制、管理等工作,两者通过electron提供的ipc api通信。
View层基本上是前端代码加上一些electron api的调用。于是,花样繁多的前端技术都可以在此使用。
既然如此,我顺便体验一下vue.js。
vue.js感受
vue.js是一个前端框架,提供数据绑定和组件管理功能。作者是华人尤雨溪,中文文档非常友好。
没错,这里的数据绑定和MVVM框架中的概念一致。只要对变量进行了修改,vue会根据依赖关系,更新对应的视图。
组件是把HTML元素进行封装,以便复用。
vue让前端代码结构分明,非常有条理。
便签的实现
对我来说,做一个项目是有趣又有效率的学习方法。
这次我做的是一个便签,和windows自带的差不多。
特性是不会遗失文字,修改后3秒自动保存,自己写的代码很放心。另外可以通过托盘、快捷键显示/隐藏便签,界面还算简洁美观。
Model层的实现
我编写了note类,提供增删等方法,使用的是lowdb这个简单的、基于json的数据库,反正便签的数据量不大。
View层的实现
vue的引入让结构很分明。 html代码里把便签的外观写出来,js里先用ipc获取便签内容,把数据绑定上去,然后注册点击按钮后的事件处理函数。
也许是写得少的原因,感觉写网页样式有点头大。css总写不出想要的效果,对着网页改来改去的,可能是之前用的Android的UI框架太方便了吧。
主进程脚本的实现
毕竟是便签,逻辑比较简单。 启动时展示上次退出时的便签,没有则创建新的。 然后用ipc监听渲染进程发来的按钮点击消息,做相应处理。 全局快捷键、托盘图标、上下文菜单之类的,教程写的很清楚(推荐这个),api用起来很方便。
托盘图标素材我是在Noun Project上找的,自己再p一下,和系统图标很协调哦。 下图最左边:
坑
上边推荐的那个教程讲得很清楚,但是有点旧。。有些代码会报错,比如导入electron模块的写法。
本来想让窗口底色透明,这样便签的样式有更大的设计空间(不规则形状、边缘阴影、半透明等等),但是会造成空闲时的CPU和GPU占用,作为便签小工具总不能太耗电吧。。于是放弃了,这个锅electron要背。
打包用的是electron-packager,要按官方文档来做,流传的教程有些是过时的。
感想
概括来说,感觉electron是前端玩具。
毕竟是个浏览器,框架文件就有100m,和其它GUI框架完全不能比较。内存占用也很大,开一个便签占40m,每加一个再多20m。而一个文件资源浏览器窗口才不到10m啊。。虽说之前有点心理准备,但看到这样的资源占用情况,我还是有些失望的。
当然,如果是代码量大、内存占用高的程序,框架的消耗就相对能接受了。然而这样的程序一般也不会用electron写界面吧。。功能上electron更适合写小程序,这就挺尴尬的。
用前端代码写界面还是相当舒服,高效又美观,而且从网页前端迁移过来的学习成本非常低。略知前端皮毛的我学习这三件套、完成这个便签本用了三天时间,可以说很容易上手了。
想到的改善资源占用问题的办法是,向Java、Flash那样先安装一个运行时,并且多个进程共享一个内核(可能会降低稳定性)。或者有朝一日,chrome内核一统天下,electron应用就不必绑着浏览器分发了。