起因是想复现港科大的无人机集群GUI界面:https://github.com/HKUST-Aerial-Robotics/swarm_gcs
这是一个用javascript写的,基于electron和nodejs的可以用浏览器打开的gui界面,其中3d显示的部分用的是Three.js。electron有一个好处是可以跨平台,目前在ubuntu20上运行(其实也可以在windows和手机端)。
1、安装nodejs和npm
因为基于nodejs,所以想需要先安装nodejs和它的包管理器npm:
sudo apt install nodejs npm
node -v # v10.19.0
npm -v # v6.14.4
下载项目源码后可以直接用npm启动:
npm start
2、安装electron
其实去读`package.json` 的 `scripts: start`可以发现本质是用 `electron .` 来启动的。所以还是得安装electron。这里应该是需要在项目本地安装而非全局:
sudo npm install electron --save-dev --verbose --unsafe-perm=true
其中 `--save-dev` 表示只将electron安装在该项目的node_modules目录下,同时`package.json`中的`devDependencies`会增加一项 "electron": "^10.4.7"。此时,全局终端里没有electron的链接。
相应的,如果用`--save` 就会`package.json`中的`Dependencies`增加一项 "electron": "^10.4.7"。
如果用 `-g` 则表示将安装至全局中,该模块依赖不会被写入devDependencies或dependencies中。此时终端输入electron可以弹出一个ui界面。
`--verbose --unsafe-perm=true` 是为了解决可能出现的网络报错,有可能还需要改淘宝源之类的。参考node.js - Unable to install electron from npm - Stack Overflow
3、用electron-packager打包
先全局安装electron-packager:
sudo npm install electron-packager -g --verbose --unsafe-perm=true
安装成功后运行electron-packager,会报错:
CANNOT RUN WITH NODE 10.19.0
Electron Packager requires Node >= 14.17.5.
说明之前安装的nodejs版本低了,但是用ubuntu20的apt只能安装到10.19.0的node。为了解决这个问题,我先apt remove卸载了之前安装的nodejs,然后在在Index of /dist/v20.0.0/下载了最新的v20.0.0版本nodejs(参考https://blog.csdn.net/huiskai/article/details/116109255)。解压后建立软链接:
sudo mv node-v20.0.0-linux-x64 /usr/local/node
sudo ln -s /usr/local/node/bin/node /usr/bin/node
sudo ln -s /usr/local/node/bin/npm /usr/bin/npm
node -v # 20.0.0
npm -v
# 删除软链接只需要rm /usr/bin/xxx就行
然后在swarm_gcs项目中对这个nodejs项目进行打包:
electron-packager . swarm_gcs --overwrite
成功后会生成一个swarm_gcs-linux-x64的文件夹(300MB),里面有一个可执行程序swarm_gcs可以直接运行(不能移动到其他地方),效果和运行npm start或者用浏览器是一样的。
打包成功后我把软链接删除了,新安装的node也删除了,用apt重新安装为了低版本的node和npm。
4、electron和Qt比较
顺便一提,Qt和electron都是可以跨平台的GUI开发框架。相比较Qt,electron的原生性没那么强(性能可能差一些,集成了webkit浏览器,导致程序打包很大。而且很难直接与c++层交互),但是更容易做出炫酷的效果(3d显示,数据交互),而且纯javascript不需要会c++。
参考:客户端开发GUI框架对比与技术选型总结_gui开发选型_HW140701的博客-CSDN博客
electron更适合做前端显示和交互界面,和ROS或者机器人交互的客户端(后端)要和前端分离开,前端和后端可以用过rosbridge进行通信(基于json,支持javascript)。