Skip to main content

使用 Electron 为 reTerminal 构建用户界面

note

本文档由 AI 翻译。如您发现内容有误或有改进建议,欢迎通过页面下方的评论区,或在以下 Issue 页面中告诉我们:https://github.com/Seeed-Studio/wiki-documents/issues

pir

简介

本篇 Wiki 讲解了如何使用 Electron 构建您自己的用户界面。Electron 是一个开源框架,用于使用 HTML、CSS 和 JavaScript 等 Web 技术创建原生桌面应用程序(Windows、Mac、Linux)。这意味着如果您可以构建一个网站,那么您也可以构建一个桌面应用程序!

通过以下指南,您将能够创建一个应用程序,通过点击 LCD 上的按钮来控制 reTerminal 的 GPIO 引脚。那么让我们开始吧!

准备开发环境

在 reTerminal 上

首先,我们将在 reTerminal 上安装 Node.jsnpm。npm 是 Node.js 包的包管理器。

  • 步骤 1. 使用 板载 LCD、外部显示器或 SSH 访问 reTerminal,具体操作请参考这里

  • 步骤 2. 升级软件包

sudo apt update
sudo apt full-upgrade
  • 步骤 3. 下载安装 Node.js 的脚本
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
  • 步骤 4. 安装 Node.js
sudo apt install -y nodejs

Node.js 现在已经安装在 reTerminal 上。要检查安装是否成功,请运行以下命令以检查 Node.jsnpm 的版本:

node -v
npm -v

pir

在主机 PC 上

现在,我们将在主机 PC 上设置 Microsoft Visual Studio Code 以进行开发。

注意: 下载适合您操作系统的安装程序

  • 步骤 2. 点击左侧导航菜单中的 扩展 标签,然后在搜索框中输入 remote development

pir

  • 步骤 3. 选择 Remote Development 并点击 安装

  • 步骤 4. 按下键盘上的 F1,输入 ssh 并选择 Remote-SSH:Connect to Host...

pir

  • 步骤 5. 输入以下内容

注意: pi 是用户名,192.xxx.xx.xx 是 reTerminal 的 IP 地址

  • 步骤 6. 输入用户的密码

现在,您已经成功通过 SSH 登录到 reTerminal,并成功完成了开发环境的准备工作。

智能灯 Electron 应用程序

现在我们将构建一个 智能灯 Electron 应用程序,通过按下 LCD 上的按钮来控制 reTerminal 的 GPIO。之后,您可以将继电器连接到 GPIO 并控制家用电器!

硬件连接

我们将把一个 LED 连接到 reTerminal 的 GPIO 24 以进行测试。稍后,您可以添加一个继电器并使用 GPIO 控制家用电器!

pir

注意: GPIO 引脚和 LED 之间需要一个电阻,否则 LED 会烧毁。

创建并初始化应用程序

  • 步骤 1. 在主机 PC 上打开 VSCode,并按照之前的说明通过 SSH 登录到 reTerminal

  • 步骤 2. 导航到 File > Open Folder...,然后选择 reTerminal 上的一个文件夹

pir

  • 步骤 3. 创建一个新文件夹并命名

pir

pir

  • 步骤 4. 导航到 Terminal > New Terminal,然后导航到新创建的文件夹

pir

注意: 这里我们使用 cd 来更改目录

  • 步骤 5. 在终端窗口中输入以下内容,以创建一个带有我们 Node.js 应用程序所需配置的 package.json 文件
npm init

注意: 持续按 ENTER 使用默认答案,但将 entry point: (index.js) 设置为 main.js,并将 test command: 设置为 electron .(在 electron 后使用一个空格和一个点)

pir

如果您想稍后更改配置,可以访问主应用程序文件夹中的 package.json 文件

pir

  • 步骤 6. 在 VSCode 的终端中输入以下内容以安装 Electron
npm install --save-dev electron

如果 Electron 成功安装,您将看到以下输出

pir

您还将看到生成的 node_modules 文件夹,其中包含运行 Electron 所需的包

pir

安装 onoff npm 模块

onoff npm 模块允许您通过 Electron 应用程序访问和控制 reTerminal 的 GPIO

  • 步骤 1. 按照之前的说明在 VSCode 中打开一个终端窗口,并导航到我们的主应用程序目录

  • 步骤 2. 输入以下内容以安装 onoff npm 模块

npm install onoff

安装并运行 electron-rebuild npm 模块

electron-rebuild npm 模块会根据您的 Electron 项目使用的 Node.js 版本重新构建本机 Node.js 模块。这使您可以在 Electron 应用程序中使用本机 Node.js 模块,而无需系统版本的 Node.js 完全匹配(这通常不是这种情况,有时甚至不可能)。

  • 步骤 1. 安装 electron-rebuild npm 模块
npm install --save-dev electron-rebuild
  • 步骤 2. 运行 electron-rebuild
./node_modules/.bin/electron-rebuild

注意: 每当您安装新的 npm 包时,请重新运行 electron-rebuild

创建 HTML(基础 UI)

我们将使用 HTML 文件创建没有任何样式的基础用户界面。此 HTML 文件负责在屏幕上显示 UI 元素。

在我们的主应用程序目录中,创建一个名为 index.html 的新文件,并复制以下代码:

<!doctype html>
<html>
<head>
<!-- 指定 HTML 文档的字符编码 -->
<meta charset="UTF-8">
<!-- 应用程序标题栏 -->
<title>测试应用程序</title>
<!-- 加载 material icons API -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<!-- 加载 Google 字体 API -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<!-- 加载带有 UI 样式的 style.css -->
<link rel="stylesheet" href="style.css">
<!-- 嵌入 JavaScript 代码 -->
<script>
// 加载 ipcRenderer 模块
const { ipcRenderer } = require('electron');
// 按下按钮时打开 GPIO 的函数
function buttonclick1()
{
// 这将以 "msg" 作为通道名称向主进程发送 1 作为消息
ipcRenderer.send("msg1",1)
}

// 按下按钮时关闭 GPIO 的函数
function buttonclick2()
{
ipcRenderer.send("msg2",0)
}

// 按下按钮时关闭应用程序的函数
function buttonclick3()
{
ipcRenderer.send("close-me")
}
</script>
</head>
<body>
<!-- 应用程序关闭按钮 -->
<button class="button3" onclick="buttonclick3()">X</button>
<br>
<!-- 应用程序标题 -->
<h1>智能灯</h1>
<!-- 来自 material icons API 的灯泡图标 -->
<i class="material-icons">lightbulb</i>
<br>
<!-- 空行 -->
<br>
<!-- 带有样式类属性的 ON 按钮
和用于按钮点击事件的 onclick 属性 -->
<button class="button1" onclick="buttonclick1()">ON</button>
<br>
<button class="button2" onclick="buttonclick2()">OFF</button>
</body>
</html>

注意: ipcRenderer 模块是一个 EventEmitter。它提供了一些方法,可以让您从渲染进程(网页 - HTML/CSS)向主进程(main.js)发送消息。您还可以从主进程接收回复。

现在我们已经完成了 HTML 文件的创建。

运行 npm test,您将看到以下输出:

pir

创建 CSS(样式)

我们将使用 CSS 文件为通过 HTML 文件创建的用户界面添加不同的样式。

在主应用程序目录中,创建一个名为 style.css 的新文件,并复制以下代码:

/* 应用程序主体的样式 */
body {
background-color: rgb(141, 141, 141);
}

/* 应用程序标题的样式 */
h1 {
font-size: 60px;
text-align: center;
font-family: "Roboto", "Courier New", monospace;
color: rgb(255, 255, 255);
}

/* 灯泡的样式 */
.material-icons{
font-size: 250px;
color: rgb(204, 202, 71);
display: flex;
justify-content: center;
}

/* ON 按钮的样式 */
.button1 {
display: inline-block;
padding: 15px 25px;
font-size: 35px;
text-align: center;
outline: none;
color: rgb(255, 255, 255);
background-color:rgb(76, 175, 80);
border: none;
border-radius: 15px;
width: 20%;
margin:auto;
display:grid;
}

/* ON 按钮的按压效果 */
.button1:active {
box-shadow: 0 5px rgb(104, 99, 99);
transform: translateY(4px);
}

/* ON 按钮的悬停效果 */
.button1:hover {background-color: rgb(62, 142, 65)}

/* OFF 按钮的样式 */
.button2 {
display: inline-block;
padding: 15px 25px;
font-size: 35px;
text-align: center;
outline: none;
color: rgb(255, 255, 255);
background-color:rgb(207, 85, 85);
border: none;
border-radius: 15px;
width: 20%;
margin:auto;
display:grid;
}

/* OFF 按钮的按压效果 */
.button2:active {
box-shadow: 0 5px rgb(104, 99, 99);
transform: translateY(4px);
}

/* OFF 按钮的悬停效果 */
.button2:hover {background-color: rgb(179, 44, 44)}

/* 关闭按钮的样式 */
.button3 {
padding: 8px 25px;
font-size: 20px;
text-align: center;
outline: none;
color: rgb(255, 255, 255);
background-color:rgb(179, 44, 44);
border: none;
width: 6%;
margin:auto;
display:grid;
float: right;
}

应用程序的最终输出如下所示:

pir

创建 Javascript(加载并执行应用程序)

我们将使用 Javascript 文件来创建应用程序窗口、加载 HTML 文件并添加 GPIO 功能。

在主应用程序目录中,创建一个名为 main.js 的新文件,并复制以下代码:

var Gpio = require('onoff').Gpio; // 引入 onoff 模块以与 GPIO 交互
var LED = new Gpio(24, 'out'); // 初始化 GPIO 24 为输出

// 引入 app、BrowserWindow 和 ipcMain 模块
const { app, BrowserWindow, ipcMain } = require('electron')
/* 使用 ipcMain 模块接收来自 ipcRenderer 模块的消息并打开 GPIO */
ipcMain.on("msg1",(event,data)=>{
LED.writeSync(data);
})

/* 使用 ipcMain 模块接收来自 ipcRenderer 模块的消息并关闭 GPIO */
ipcMain.on("msg2",(event,data)=>{
LED.writeSync(data);
})

/* 使用 ipcMain 模块接收来自 ipcRenderer 模块的消息并关闭应用程序 */
ipcMain.on("close-me", (event, arg) => {
app.quit()
})

// 创建应用程序窗口
app.on('ready', function() {
var mainWindow = new BrowserWindow({
// 使应用程序全屏
"fullscreen": true,
webPreferences: {
// 启用主进程与渲染进程之间的通信
nodeIntegration: true,
contextIsolation: false
}
});
// 加载带有 CSS 样式的 HTML 页面
mainWindow.loadFile('index.html');
});

注意: ipcMain 提供了一些方法,可以接收从渲染进程(网页)发送的消息。

测试应用程序

由于我们已经启用了 electron-rebuild,保存前面的文件后,您将立即看到输出。然而,如果您关闭了应用程序,可以通过运行 npm test 再次打开它,并看到以下输出:

pir

准备运行应用程序的脚本

  • 步骤 1. 打开我们之前创建的根文件夹,并在该文件夹下创建一个新的 .sh 文件

pir

  • 步骤 2. 打开创建的文件并输入以下内容
#!/bin/bash
cd $HOME/Desktop/testapp
DISPLAY=:0 npm test

注意: 这里 $HOME/Desktop/testapp 是 Electron 项目的位置

  • 步骤 3. 在 VSCode 中打开一个终端窗口并导航到应用程序的根目录
示例:
cd ~/Desktop/testapp
  • 步骤 4. 将 ledstart.sh 文件设置为可执行文件
sudo chmod +x ledstart.sh

准备一个桌面文件以启动应用程序

  • 步骤 1. 打开 Desktop 文件夹,并在该文件夹下创建一个新的 .desktop 文件

pir

  • 步骤 2. 打开创建的文件并输入以下内容
[Desktop Entry]
Encoding=UTF-8
Name=LED Test
Comment=IconTest Link
Exec=/home/pi/Desktop/testapp/ledStart.sh
Type=Application
Categories=Application;Development;

注意: Exec 是我们之前创建的脚本的位置

  • 步骤 3. 在 VSCode 中打开一个终端窗口并导航到 Desktop 文件夹
示例:
cd ~/Desktop
  • 步骤 4.ledStart.desktop 文件设置为可执行文件
sudo chmod +x ledStart.desktop

启动应用程序

双击 reTerminal LCD 桌面上的 LED Test 文件

您将看到如下输出

pir

现在您可以点击按钮,您将看到 LED 灯亮起!

调试应用程序

让我们了解在开发过程中调试应用程序的流程

  • 步骤 1. 使用 Microsoft Visual Studio Code 通过 SSH 登录到 reTerminal

  • 步骤 2. 使用支持 X11 服务器功能 的 SSH 应用程序(例如 MobaXterm)通过 SSH 登录到 reTerminal

注意: X11 需要将 reTerminal 显示转发并弹出到 PC 上

  • 步骤 3. 在 Microsoft Visual Studio Code 中编写所有代码到 reTerminal 后,导航到主应用程序目录并运行以下命令
npm test

最终,您将在新窗口中看到输出。如果代码中有任何错误,它们将显示在 MobaXterm 的终端窗口中。

常见问题

问: 如何设置应用程序的自动更新功能以便在保存时更新?

为此,您可以使用 electron-reloader npm 模块设置热重载功能

  • 步骤 1. 安装 electron-reloader
npm install --save-dev electron-reloader
  • 步骤 2.main.js 文件的末尾添加以下代码
try {
require('electron-reloader')(module)
} catch (_) {}

现在使用 npm test 运行文件一次,应用程序将在您保存文件时自动更新。您不需要每次更改项目内容时都运行 npm test

额外演示

如果您想体验一个更有趣的基于 Electron 的演示,可以查看 这个 GitHub 仓库

pir

资源

技术支持与产品讨论

感谢您选择我们的产品!我们致力于为您提供多种支持,以确保您使用我们的产品时获得顺畅的体验。我们提供了多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...