4.1 创建主窗口
主窗口是 Electron 应用启动后显示的第一个窗口,通常用来承载应用的主界面。我们使用 BrowserWindow
类来创建主窗口。
4.1.1 创建主窗口的基础代码
// 引入 Electron 模块和 Node.js 的 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, 'preload.js'), // 指定预加载脚本contextIsolation: true, // 启用上下文隔离nodeIntegration: false // 禁用 Node.js 集成}});// 加载主窗口的 HTML 文件mainWindow.loadFile('index.html');// 打开开发者工具(仅在开发阶段使用)mainWindow.webContents.openDevTools();// 监听主窗口的关闭事件mainWindow.on('closed', () => {// 当窗口被关闭时,将 mainWindow 设置为 nullmainWindow = 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, 'preload.js'), // 指定预加载脚本contextIsolation: true, // 启用上下文隔离nodeIntegration: false // 禁用 Node.js 集成}});// 加载子窗口的 HTML 文件childWindow.loadFile('child.html');// 监听子窗口的关闭事件childWindow.on('closed', () => {// 当窗口被关闭时,将 childWindow 设置为 nullchildWindow = 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 创建预加载脚本
preload.js:
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>// 使用预加载脚本暴露的 APIdocument.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, 'preload.js'),contextIsolation: true,nodeIntegration: false}});childWindow.loadFile('child.html');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');// 隐藏子窗口 child1hideChildWindow('child1');// 2 秒后显示子窗口 child1setTimeout(() => {showChildWindow('child1');}, 2000);
});
通过本章内容,你已经了解了如何在 Electron 中创建和管理主窗口及子窗口,包括如何进行窗口间通信、使用预加载脚本提高安全性、管理多个窗口以及显示和隐藏窗口的操作。在接下来的章节中,我们将进一步探讨如何实现更多高级功能和最佳实践,帮助你进一步掌握 Electron 开发。