4.1 创建主窗口
主窗口是 Electron 应用启动后显示的第一个窗口,通常用来承载应用的主界面。我们使用 BrowserWindow
类来创建主窗口。
4.1.1 创建主窗口的基础代码
// 引入 Electron 模块和 的 path 模块
const { app, BrowserWindow } = require('electron');
const path = require('path');
// 定义一个变量用于存储主窗口对象
let mainWindow;
// 创建主窗口的函数
const createMainWindow = () => {
// 实例化 BrowserWindow 对象
mainWindow = new BrowserWindow({
width: 800, // 窗口宽度
height: 600, // 窗口高度
webPreferences: {
preload: path.join(__dirname, ''), // 指定预加载脚本
contextIsolation: true, // 启用上下文隔离
nodeIntegration: false // 禁用 集成
}
});
// 加载主窗口的 HTML 文件
mainWindow.loadFile('');
// 打开开发者工具(仅在开发阶段使用)
mainWindow.webContents.openDevTools();
// 监听主窗口的关闭事件
mainWindow.on('closed', () => {
// 当窗口被关闭时,将 mainWindow 设置为 null
mainWindow = null;
});
};
// 当 Electron 完成初始化并准备创建浏览器窗口时,调用 createMainWindow 函数
app.on('ready', createMainWindow);
// 当所有窗口关闭时,退出应用(除非在 macOS 上)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
// 当应用被激活时(例如在 macOS 上单击应用图标),重新创建主窗口
app.on('activate', () => {
if (mainWindow === null) {
createMainWindow();
}
});
4.2 创建子窗口
子窗口用于显示辅助内容或执行辅助任务。与主窗口类似,子窗口也是通过 BrowserWindow
类创建的。
4.2.1 创建子窗口的示例代码
// 创建子窗口的函数
const createChildWindow = () => {
// 实例化 BrowserWindow 对象
let childWindow = new BrowserWindow({
parent: mainWindow, // 设置父窗口为主窗口
modal: true, // 设置为模态窗口
width: 400, // 窗口宽度
height: 300, // 窗口高度
webPreferences: {
preload: path.join(__dirname, ''), // 指定预加载脚本
contextIsolation: true, // 启用上下文隔离
nodeIntegration: false // 禁用 集成
}
});
// 加载子窗口的 HTML 文件
childWindow.loadFile('');
// 监听子窗口的关闭事件
childWindow.on('closed', () => {
// 当窗口被关闭时,将 childWindow 设置为 null
childWindow = null;
});
};
// 在主窗口创建完成后创建子窗口
app.on('ready', () => {
createMainWindow();
createChildWindow();
});
4.3 窗口间通信
通过 IPC 机制,主窗口和子窗口可以相互通信。这里使用 ipcMain
和 ipcRenderer
模块实现通信。
4.3.1 主窗口与子窗口之间的通信示例
主进程:
const { ipcMain } = require('electron');
// 监听从渲染进程发送的消息
ipcMain.on('message-from-child', (event, arg) => {
console.log('Received message from child:', arg);
// 回复消息到渲染进程
event.reply('reply-from-main', 'Message received by main process');
});
4.4 预加载脚本
预加载脚本在渲染进程加载前执行,允许在渲染器上下文中暴露自定义 API,并提供与主进程安全通信的桥梁。
4.4.1 创建预加载脚本
:
const { contextBridge, ipcRenderer } = require('electron');
// 使用 contextBridge 将安全的 API 暴露给渲染进程
contextBridge.exposeInMainWorld('electronAPI', {
sendMessage: (message) => ipcRenderer.send('message-from-child', message),
onReply: (callback) => ipcRenderer.on('reply-from-main', (event, args) => callback(args))
});
4.4.2 在渲染进程中使用预加载脚本
子窗口(渲染进程):
<!DOCTYPE html>
<html>
<head>
<title>Child Window</title>
</head>
<body>
<h1>Child Window</h1>
<button id="sendMessageBtn">Send Message to Main</button>
<script>
// 使用预加载脚本暴露的 API
document.getElementById('sendMessageBtn').addEventListener('click', () => {
window.electronAPI.sendMessage('Hello from child window');
});
window.electronAPI.onReply((message) => {
console.log('Received reply from main:', message);
});
</script>
</body>
</html>
4.5 管理多个窗口
在复杂的应用中,可能需要同时管理多个窗口。可以通过存储窗口实例的数组或对象来实现这一点。
4.5.1 管理多个窗口的示例
const windows = {};
// 创建子窗口的函数
const createChildWindow = (windowName) => {
let childWindow = new BrowserWindow({
parent: mainWindow,
modal: true,
width: 400,
height: 300,
webPreferences: {
preload: path.join(__dirname, ''),
contextIsolation: true,
nodeIntegration: false
}
});
childWindow.loadFile('');
childWindow.on('closed', () => {
// 当窗口被关闭时,从 windows 对象中删除对应的实例
delete windows[windowName];
});
// 将窗口实例存储到 windows 对象中
windows[windowName] = childWindow;
};
// 创建多个子窗口
app.on('ready', () => {
createMainWindow();
createChildWindow('child1');
createChildWindow('child2');
});
4.6 窗口的显示和隐藏
有时需要在应用中显示或隐藏窗口,而不是创建或销毁它们。
4.6.1 显示和隐藏窗口的示例
// 显示子窗口
const showChildWindow = (windowName) => {
if (windows[windowName]) {
windows[windowName].show();
}
};
// 隐藏子窗口
const hideChildWindow = (windowName) => {
if (windows[windowName]) {
windows[windowName].hide();
}
};
// 在主窗口创建完成后创建子窗口并演示显示和隐藏功能
app.on('ready', () => {
createMainWindow();
createChildWindow('child1');
// 隐藏子窗口 child1
hideChildWindow('child1');
// 2 秒后显示子窗口 child1
setTimeout(() => {
showChildWindow('child1');
}, 2000);
});
通过本章内容,你已经了解了如何在 Electron 中创建和管理主窗口及子窗口,包括如何进行窗口间通信、使用预加载脚本提高安全性、管理多个窗口以及显示和隐藏窗口的操作。在接下来的章节中,我们将进一步探讨如何实现更多高级功能和最佳实践,帮助你进一步掌握 Electron 开发。