在桌面应用开发中,窗口状态的控制是最基础也最高频的操作。Electron 的 BrowserWindow 实例提供了一套直观的方法,让你可以像操作一个普通桌面窗口一样,在代码中随时调整它的显示、隐藏、最小化、最大化和关闭行为。这些方法通常在主进程中调用,但通过 IPC 也可以让渲染进程(界面)来触发,从而实现用户点击界面按钮来控制窗口的需求。
1. 显示与隐藏
窗口的显示和隐藏是最常用的操作之一,尤其是在需要临时隐藏窗口(比如点击关闭按钮后最小化到托盘、程序启动时先隐藏主窗口等场景)。
win.show():显示窗口。通常在窗口创建后调用,或者窗口被隐藏后重新显示。win.hide():隐藏窗口。窗口不会销毁,只是不可见,类似于点击了最小化到任务栏以外的隐藏。win.isVisible():返回布尔值,判断窗口当前是否可见。
使用示例:
// 主进程
const { BrowserWindow } = require('electron');
const win = new BrowserWindow({ show: false }); // 创建时不自动显示
// 准备就绪后再显示窗口,避免白屏
win.once('ready-to-show', () => {
win.show();
});
// 某个条件下隐藏窗口
ipcMain.on('hide-window', () => {
win.hide();
});
实际场景:很多应用在启动时先加载界面,等所有内容渲染完毕再显示窗口,这样可以避免用户看到丑陋的白屏或闪烁。ready-to-show 事件配合 show: false 的初始设置就是这个用途。此外,一些工具类应用(如截图、词典)会先用一个悬浮窗显示信息,不需要时 hide() 隐藏,需要时 show() 再次出现。
2. 最小化与恢复
最小化会将窗口缩小到任务栏(Windows)或程序坞(macOS),窗口仍然在后台运行,用户随时可以恢复。
win.minimize():最小化窗口。win.restore():将最小化的窗口恢复到之前的大小和位置。如果窗口当前是最小化状态,调用此方法会复原;如果是最大化状态,则还原到普通状态。win.isMinimized():判断窗口是否已最小化。
使用示例:
// 最小化窗口(例如在界面某个按钮触发)
ipcMain.on('minimize-window', () => {
win.minimize();
});
// 监听窗口最小化事件
win.on('minimize', () => {
console.log('窗口已最小化');
});
实际场景:通常在应用的标题栏或菜单中提供“最小化”按钮。你也可以在退出全屏或处理一些自动化任务时,调用 restore() 确保窗口处于正常显示状态。
3. 最大化与全屏
最大化指窗口铺满整个屏幕的可视区域(不覆盖任务栏/程序坞),而全屏则是完全占据整个屏幕,可能隐藏系统 UI。
win.maximize():最大化窗口。win.unmaximize():取消最大化,恢复为之前的尺寸和位置。win.isMaximized():判断窗口是否最大化。win.setFullScreen(flag):切换全屏模式,flag为true进入全屏,false退出全屏。win.isFullScreen():判断是否处于全屏状态。
使用示例:
ipcMain.on('toggle-maximize', () => {
if (win.isMaximized()) {
win.unmaximize();
} else {
win.maximize();
}
});
// 进入全屏模式(例如视频播放)
ipcMain.on('enter-fullscreen', () => {
win.setFullScreen(true);
});
实际场景:多媒体播放器、设计软件、IDE 等通常都提供全屏模式以最大化工作区域。最大化则是常规的窗口操作。需要注意的是,在 macOS 上最大化行为可能与 Windows 略有不同(macOS 是“缩放”),但 Electron 已经做了统一处理。
4. 关闭窗口与程序退出
关闭窗口对应的是用户点击窗口右上角的关闭按钮,但你可以控制这个行为——比如隐藏到托盘而不是直接退出程序。
win.close():尝试关闭窗口。这会触发close事件,你可以在该事件中阻止默认关闭行为。win.destroy():强制销毁窗口,不会触发close事件,一般用于程序退出时清理。win.closed属性:窗口是否已被关闭或销毁。
结合事件控制关闭行为:
win.on('close', (event) => {
// 阻止默认关闭,改为隐藏到托盘
event.preventDefault();
win.hide();
});
// 真正的退出(例如托盘菜单的退出选项)
ipcMain.on('quit-app', () => {
app.quit(); // app.quit() 会关闭所有窗口并触发 before-quit 事件
});
实际场景:很多即时通讯软件(如微信、Slack)点击关闭按钮并不是真正退出,而是最小化到系统托盘继续接收消息。这可以通过监听 close 事件并 preventDefault,然后 hide() 实现。当用户从托盘右键菜单选择“退出”时,再调用 app.quit() 真正结束进程。
5. 窗口状态控制的整体实践
一个常见的完整模式是:在应用中创建无边框窗口或自定义标题栏,然后通过渲染进程发送 IPC 事件来触发窗口状态操作。
渲染进程代码(例如 Vue/React 组件中):
// 预加载脚本暴露的 API
window.electronAPI.minimize();
window.electronAPI.maximize();
window.electronAPI.close();
// 或者通过 ipcRenderer.invoke 调用主进程方法
await window.electronAPI.invoke('minimize');
主进程对应的 IPC 处理:
ipcMain.handle('minimize', () => win.minimize());
ipcMain.handle('maximize', () => {
win.isMaximized() ? win.unmaximize() : win.maximize();
});
ipcMain.handle('close', () => win.close());
注意:在 macOS 上,当所有窗口关闭时,应用默认不会退出(这是平台惯例),除非你监听了 app.on('window-all-closed') 并调用 app.quit()。通常建议保留这个行为,不过可以用条件判断在非 macOS 平台退出:
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
窗口状态控制虽然简单,却是构成良好用户体验的基石。通过这几组方法,你可以灵活地管理应用的可见性、窗口尺寸以及与系统桌面的交互方式,让 Electron 应用的行为更符合一个标准原生软件的操作习惯。