Electron窗口与菜单

时游大约 3 分钟

Electron 窗口与菜单

BrowserWindow 常用配置

const win = new BrowserWindow({
	width: 1200,
	height: 800,
	minWidth: 800,           // 最小尺寸
	minHeight: 600,
	x: 100, y: 100,          // 窗口位置(不设置则居中)
	center: true,            // 屏幕居中
	resizable: true,         // 是否可调整大小
	frame: true,             // false 为无边框窗口
	titleBarStyle: "hidden", // mac 隐藏标题栏(配合 trafficLightPosition)
	icon: "./logo.png",
	transparent: false,      // 透明窗口需 frame: false
	show: false,             // 先隐藏,ready-to-show 后再显示,避免白屏
	webPreferences: {
		preload: path.join(__dirname, "preload.js"),
		contextIsolation: true,  // 默认开启,渲染进程与 preload 隔离
		nodeIntegration: false   // 默认关闭,不暴露 Node API 给页面
	}
});

// 配合 show: false 消除启动白屏
win.once("ready-to-show", () => win.show());

窗口控制 API

win.loadURL("https://example.com");   // 加载远程地址
win.loadFile("./dist/index.html");    // 加载本地文件
win.webContents.reload();             // 刷新
win.close();                          // 关闭
win.minimize();                       // 最小化
win.maximize();                       // 最大化
win.unmaximize();
win.hide(); / win.show();             // 隐藏/显示

// 父子窗口:模态对话框
const child = new BrowserWindow({ parent: win, modal: true, width: 400, height: 300 });

// 获取当前焦点窗口
const focused = BrowserWindow.getFocusedWindow();

应用菜单(Menu)

macOS 应用必须有顶部菜单栏;Windows/Linux 可隐藏。

创建自定义菜单

const { app, Menu } = require("electron");

const template = [
	{
		label: "文件",
		submenu: [
			{
				label: "新建窗口",
				accelerator: "CmdOrCtrl+N",       // 快捷键
				click: () => createWindow()
			},
			{ type: "separator" },                 // 分隔线
			{
				label: "打开开发者工具",
				accelerator: "F12",
				click: (_, browserWindow) => {
					browserWindow?.webContents.toggleDevTools();
				}
			},
			{ role: "quit", label: "退出" }        // role 使用系统预置行为
		]
	},
	{
		label: "编辑",
		submenu: [
			{ role: "undo", label: "撤销" },
			{ role: "redo", label: "重做" },
			{ role: "cut", label: "剪切" },
			{ role: "copy", label: "复制" },
			{ role: "paste", label: "粘贴" },
			{ role: "selectAll", label: "全选" }
		]
	},
	{
		label: "视图",
		submenu: [
			{ role: "reload", label: "刷新" },
			{ role: "toggleDevTools", label: "开发者工具" },
			{ role: "zoomIn", label: "放大" },
			{ role: "zoomOut", label: "缩小" },
			{ role: "resetZoom", label: "重置缩放" },
			{ role: "togglefullscreen", label: "全屏" }
		]
	}
];

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

Windows/Linux 下想彻底去掉菜单栏:Menu.setApplicationMenu(null);macOS 不允许为空,可只保留一个应用菜单。

常用 role 一览

role行为role行为
undo / redo撤销/重做reload刷新页面
cut/copy/paste剪切/复制/粘贴toggleDevTools开发者工具
selectAll全选togglefullscreen全屏切换
minimize最小化zoomIn / zoomOut缩放
close关闭窗口quit退出应用

右键菜单(上下文菜单)

const { Menu } = require("electron");

// 主进程中监听渲染进程的右键菜单请求(配合 IPC 使用)
const contextMenu = Menu.buildFromTemplate([
	{ label: "复制", role: "copy" },
	{ label: "粘贴", role: "paste" },
	{ type: "separator" },
	{
		label: "检查元素",
		click: (_, browserWindow) => {
			browserWindow?.webContents.inspectElement(x, y);
		}
	}
]);

contextMenu.popup({ window: BrowserWindow.fromWebContents(webContents) });

系统托盘(Tray)

const { Tray, Menu, nativeImage, app } = require("electron");

let tray = null;

app.whenReady().then(() => {
	// 托盘图标(建议 16x16/32x32 png)
	const icon = nativeImage.createFromPath(path.join(__dirname, "tray.png"));
	tray = new Tray(icon);

	const contextMenu = Menu.buildFromTemplate([
		{ label: "显示主窗口", click: () => win?.show() },
		{ type: "separator" },
		{ label: "退出", click: () => app.quit() }
	]);

	tray.setToolTip("我的应用");        // 悬停提示
	tray.setContextMenu(contextMenu);  // 左键点击弹出的菜单

	// mac 上点击托盘图标本身的行为
	tray.on("click", () => win?.show());
});

点击窗口关闭按钮时若想最小化到托盘而不是退出:监听窗口 close 事件,event.preventDefault() 后 win.hide()。

dock 图标角标(macOS)

app.dock.setBadge("99+");   // 设置角标文字
app.dock.getBadge();
Loading...