Electron:构建跨平台桌面应用的现代方法

环境搭建与Hello World

main.js (主进程)

const { app, BrowserWindow } = require('electron')

function createWindow () {
  // 创建一个新的浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800, // 窗口宽度
    height: 600, // 窗口高度
    webPreferences: {
      nodeIntegration: true, // 允许Node.js集成
      contextIsolation: false, // 如果使用了contextBridge,则应设为true
      enableRemoteModule: true // 是否启用remote模块
    }
  })

  // 加载index.html文件
  mainWindow.loadFile('index.html')

  // 打开开发者工具
  // mainWindow.webContents.openDevTools()
}

// 当Electron完成初始化并准备好创建浏览器窗口时调用此方法
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // 在macOS上,当点击dock图标并且没有其他窗口打开时,
    // 通常在应用程序中重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 关闭所有窗口时退出应用
app.on('window-all-closed', function () {
  // 在macOS上,除非用户按下Cmd + Q明确退出,
  // 否则应用程序及其菜单栏将保留在后台。
  if (process.platform !== 'darwin') app.quit()
})

index.html (渲染进程)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello World!</title>
  <!-- 引入样式 -->
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <h1>Hello World!</h1>
  <script>
    // 这里可以写渲染进程的JavaScript代码
    console.log('This is from renderer process.');
  </script>
</body>
</html>

styles.css (样式)

body {
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  font-family: Arial, sans-serif;
  background-color: #f0f0f0;
}
h1 {
  color: #333;
}

主进程与渲染进程通信示例

假设我们要从渲染进程发送一条消息给主进程,并由主进程处理后回复。

main.js 添加以下代码:

const { ipcMain } = require('electron')

// 监听来自渲染进程的消息
ipcMain.on('asynchronous-message', (event, arg) => {
  console.log(arg) // 打印接收到的消息
  event.sender.send('asynchronous-reply', 'pong') // 回复消息给渲染进程
})
index.html 中的JavaScript部分添加:

javascript
const { ipcRenderer } = require('electron')

document.getElementById('sendBtn').addEventListener('click', () => {
  ipcRenderer.send('asynchronous-message', 'ping') // 发送消息给主进程
})

// 监听主进程的回复
ipcRenderer.on('asynchronous-reply', (event, arg) => {
  console.log(arg) // 打印接收到的回复
})

窗口管理与菜单

窗口管理示例

创建新窗口

在main.js中,可以定义一个函数来创建新的窗口:

function createNewWindow() {
  const newWindow = new BrowserWindow({
    width: 400,
    height: 300,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true
    }
  })
  newWindow.loadFile('newWindow.html')
}

并在某个事件中调用这个函数,比如在主窗口中点击按钮触发新窗口的创建。

菜单示例

创建一个简单的菜单:

main.js

const { Menu } = require('electron')

const template = [
  {
    label: 'File',
    submenu: [
      {
        label: 'Open',
        accelerator: 'CmdOrCtrl+O',
        click() { /* 执行打开文件的逻辑 */ }
      },
      {
        label: 'Save',
        accelerator: 'CmdOrCtrl+S',
        click() { /* 执行保存文件的逻辑 */ }
      },
      { type: 'separator' },
      { role: 'quit' }
    ]
  },
  // 其他菜单项...
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)

文件系统操作

读取文件示例

const fs = require('fs')

fs.readFile('path/to/your/file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(data)
})

保存文件示例

fs.writeFile('path/to/your/newfile.txt', 'Hello Electron!', err => {
  if (err) throw err
  console.log('The file has been saved!')
})

打包与分发

使用electron-builder进行打包:

首先安装electron-builder

npm install --save-dev electron-builder

然后在package.json中配置打包信息:

{
  "name": "your-app-name",
  "version": "1.0.0",
  "build": {
    "appId": "com.yourcompany.yourapp",
    "mac": {
      "category": "public.app-category.developer-tools"
    },
    "win": {
      "target": ["nsis"]
    }
  }
}

最后,运行打包命令:

# 打包为macOS应用
npm run build -- -m

# 打包为Windows应用
npm run build -- -w

自动更新

首先,安装electron-updater

npm install --save-dev electron-updater

在main.js中引入并配置自动更新:

const { autoUpdater } = require('electron-updater')

autoUpdater.checkForUpdatesAndNotify()

autoUpdater.on('update-available', () => {
  dialog.showMessageBox({
    title: 'Update available',
    message: 'A new version is available. It will be downloaded in the background.'
  })
})

autoUpdater.on('update-downloaded', () => {
  dialog.showMessageBox({
    title: 'Update ready',
    message: 'The update has been downloaded. It will be installed on restart.'
  }).then(() => {
    autoUpdater.quitAndInstall()
  })
})

2500G计算机入门到高级架构师开发资料超级大礼包免费送!

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯学馆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值