常用模块
菜单管理
菜单栏
下面先来学习不显示默认菜单,在主进程 main.js 中定义以下代码
const { BrowserWindow, app, Menu } = require('electron')
Menu.setApplicationMenu(null)我们需要用到 Menu 模块、MenuItem 菜单项与 accelerator 快捷键知识
const { app, Menu } = require('electron')
//是否是苹果系统
const isMac = process.platform === 'darwin'
const template = [
{
label: '百度',
submenu: [
{
label: '打开新窗口',
click: () => {
const win = new BrowserWindow({
width: 300,
height: 300,
})
win.loadURL('https://www.baidu.com')
},
},
//分隔线
{
type: 'separator',
},
{
label: '退出',
click: async () => app.quit(),
//定义快捷键
accelerator: 'CommandOrControl+q',
},
//渲染进程触发主进程通信
{
click: () => mainWindow.webContents.send('update-counter', 1),
label: 'Increment',
},
isMac
? { label: '关闭', role: 'close' }
: { role: 'quit' },
],
},
{
label: 'github',
submenu: [
{
label: 'www.github.com',
},
],
},
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)右键菜单
electron 可以定义快捷右键菜单,需要预加载脚本与主进程结合使用
main.js 主进程定义 ipc 事件,当 preload.js 触发事件时显示右键菜单
ipcMain.on('show-context-menu', (event) => {
const popupMenuTemplate = [
{ label: '退出', click: () => app.quit() },
]
const menu = Menu.buildFromTemplate(
popupMenuTemplate,
)
menu.popup(
BrowserWindow.fromWebContents(event.sender),
)
})preload.js 预加载脚本定义,用于触发右键事件,然后通过IPC调用主进程显示右键菜单
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
ipcRenderer.send('show-context-menu')
})对话框
dialog 模块用于打开和保存文件、显示警告或确认消息框等功能,dialog 运行于主进程中
错误消息
使用 showErrorBox 可以控制显示错误消息,两个参数第一个参数是标题,第一个参数是显示内容
dialog.showErrorBox('通知', '你没有接收协议')消息框
使用 showMessageBox 或 showMessageBoxSync 显示消息框,返回结果是点击的按钮索引,然后你可以根据不同点击的按钮实现不同的业务。
建议使用 showMessageBox 异步方法处理消息框
app.whenReady().then(async () => {
createWindow()
const res = await dialog.showMessageBox({
type: 'warning',
title: '你要退出吗?',
detail: '有问题吗?',
buttons: ['取消', '退出'],
//取消按钮的索引,使用esc根据索引调用取消按钮,默认为0,所以建议在buttons中将取消设置为第一个
cancelId: 0,
checkboxLabel: '接收协议',
checkboxChecked: false,
})
if (!res.checkboxChecked) return dialog.showErrorBox('通知', '你没有接收协议')
if (res.response == 1) app.quit()
})选择文件
main.js 主进程,定义 IPC 通信事件 fileDialog 用于被渲染进程调用
...
app.whenReady().then(() => {
createWindow()
ipcMain.handle('fileDialog', () => {
return dialog.showOpenDialog({
//对话框窗口的标题
title: '选择文件',
//选择文件、目录,并支持多选
properties: [
'openFile',
'openDirectory',
'multiSelections',
],
//文件类型限制
filters: [
{
name: 'Images',
extensions: ['jpg', 'png', 'gif'],
},
],
})
})
})
...preload.js 预加载脚本,用于向主进程 main.js 发送 IPC 通信,调用 dialog 模块选择文件
const {
contextBridge,
ipcRenderer,
} = require('electron/renderer')
contextBridge.exposeInMainWorld('api', {
selectFiles: () => {
return ipcRenderer.invoke('fileDialog')
},
})renderer.js 渲染脚本,使用 IPC 通信通过 preload.js 调用主进程任务,并将dialog获取到的文件路径放入DOM #files 标签中
const bt = document.querySelector('#btn')
bt.addEventListener('click', async () => {
const res = await api.selectFiles()
document.querySelector('#files').innerHTML =
res.filePaths.join('<br/>')
})index.html 模板
#btn按钮用于触发IPC通信#files标签用于显示 dialog 获取的文件列表
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'" />
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'" />
<title>houdunren</title>
</head>
<body>
<button id="btn">选择文件</button>
<div id="files"></div>
<script src="renderer.js"></script>
</body>
</html>保存文件
使用 showSaveDialogSync 与 showSaveDialog 接口用于保存文件
下面是使用 dialog 保存文件的示例
main.js 主进程,使用 dialog 模块选择文件保存位置,并调用 node 的 fs 模块写入文件
app.whenReady().then(() => {
createWindow()
ipcMain.handle('saveFileDialog', async () => {
const res = await dialog.showSaveDialog({
//默认文件名
defaultPath: fileName,
//对话框窗口的标题
title: '保存壁纸图片',
message: '',
//允许创建目录
properties: ['createDirectory']
})
writeFileSync(res.filePath, 'wenjainming')
return res
})
})preload.js 预加载脚本,用于向主进程main.js发送IPC通信,调用 dialog 模块保存文件
const {
contextBridge,
ipcRenderer,
} = require('electron/renderer')
contextBridge.exposeInMainWorld('api', {
saveFile: () => {
return ipcRenderer.invoke('saveFileDialog')
},
})renderer.js 渲染脚本,使用 IPC 通信通过 preload.js 调用主进程任务,并将 dialog 保存文件
const bt = document.querySelector('#btn')
bt.addEventListener('click', async () => {
const res = await api.saveFile()
})index.html 模板,定义#btn按钮用于触发保存文件的 IPC 通信
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'" />
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'" />
<title>houdunren</title>
</head>
<body>
<button id="btn">保存文件</button>
<div id="files"></div>
<script src="renderer.js"></script>
</body>
</html>通知消息
Mac、Windows、Linux 三个操作系统都为应用程序向用户发送通知提供了手段。 在主进程和渲染进程中,显示通知的技术不同的
对于渲染进程,Electron 方便地允许开发者使用 HTML5 通知 API 发送通知,要在主进程中显示通知,您需要使用 Notification 模块
渲染进程
渲染进程可以使用 HTML5 通知 API 发送通知
renderer.js
const bt = document.querySelector('#btn')
bt.addEventListener('click', async () => {
new Notification('通知', {
body: '记得每天多喝水',
})
})index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'" />
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'" />
<title>houdunren</title>
</head>
<body>
<button id="btn">发送通知</button>
<div id="files"></div>
<script src="renderer.js"></script>
</body>
</html>主进程
主进程发送通知需要使用 Notification 模块
下面是main.js主进程发送通知示例
app.whenReady().then(() => {
createWindow()
new Notification({
title: '通知',
body: '得每天多喝水',
}).show()
})