Electron
的 Menu
模块。下面是个例子:
const { app, BrowserWindow, Menu } = require('electron') // 创建菜单模板 const myMenus = [ { label: '文件', submenu: [ { label: '打开', accelerator: 'CmdOrCtrl+O', // 快捷键 click() { // 处理打开操作 } }, { label: '保存', accelerator: 'CmdOrCtrl+S', click() { // 处理保存操作 } }, { type: 'separator' // 添加分隔线 }, { label: '退出', accelerator: 'CmdOrCtrl+Q', click() { app.quit(); // 退出应用程序 } } ] }, { label: '编辑', submenu: [ { role: 'undo' }, { role: 'redo' }, { type: 'separator' }, { role: 'cut' }, { role: 'copy' }, { role: 'paste' }, { role: 'pasteAndMatchStyle' }, { role: 'delete' }, { role: 'selectAll' } ] } ]; // 创建菜单 const menu = Menu.buildFromTemplate(myMenus); // 将菜单设置为应用程序的菜单 Menu.setApplicationMenu(menu) app.on('ready', () => { const win = new BrowserWindow({ width: 800, height: 600 }) })
当涉及 Electron 的 Menu
模块时,以下是一些主要的知识点:
创建菜单:使用
Menu.buildFromTemplate(template)
方法可以根据提供的菜单模板创建菜单对象。菜单模板是一个包含菜单项的数组,每个菜单项都有自己的属性,如标签(label)、快捷键(accelerator)、角色(role)和点击事件(click)等。设置应用程序菜单:使用
Menu.setApplicationMenu(menu)
方法可以将菜单设置为应用程序的菜单。通过调用这个方法,你可以在应用程序的菜单栏或窗口中显示自定义的菜单。菜单项属性:
label
:菜单项显示的文本。accelerator
:为菜单项指定快捷键,允许用户使用键盘快速访问菜单项。click
:菜单项被点击时触发的回调函数。role
:使用内置的角色来指定一些常见操作的行为,如复制('copy')、剪切('cut')、粘贴('paste')等。这些角色会根据操作系统的约定自动处理相应的操作。submenu
:指定一个子菜单,允许创建层级嵌套的菜单。分隔线和标签:通过在菜单模板中使用
type: 'separator'
可以添加分隔线,用于在菜单中分隔不同的菜单项。你还可以使用type: 'label'
来创建一个标签,它是一个不可点击的文本项,用于在菜单中提供额外的说明或分组。上下文菜单:除了应用程序菜单,你还可以创建上下文菜单(也称为右键菜单)。通过监听特定的事件(如
contextmenu
),可以在合适的时候显示自定义的上下文菜单。
菜单项和role相关的信息可以参考:https://www.electronjs.org/zh/docs/latest/api/menu-item
右键菜单
自定义右键菜单和自定义应用菜单用法基本差不多,也是通过Menu
模块实现的。由于右键菜单的显示一般发生在渲染进程中,所有我们需要使用进程间通信和预处理脚本。下面是一个例子:
// 主进程 main.js const { app, BrowserWindow, Menu, ipcMain } = require('electron') const path = require('path') // 1.创建菜单模板 const myMenus = [ { label: '菜单1', accelerator: 'CmdOrCtrl+O', // 快捷键 click() { // 处理打开操作 } }, { label: '菜单2', submenu: [ { role: 'undo' }, { role: 'redo' }, { type: 'separator' }, { role: 'cut' }, { role: 'copy' }, { role: 'paste' }, { role: 'delete' }, { role: 'selectAll' } ] } ]; // 2.创建菜单 const menu = Menu.buildFromTemplate(myMenus); app.on('ready', () => { // 创建窗口 const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'p1.js') } }) win.loadFile('index.html') // 监听子进程的showContextMenu频道 ipcMain.on('showContextMenu', function () { // 3.在窗口中显示右键菜单 menu.popup() }) })
// 预处理脚本文件 p1.js const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('elecAPI', { showContextMenu: function () { // 向主进程showContextMenu频道发送信息 ipcRenderer.send('showContextMenu') } })
<!-- 渲染进程中的代码 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>您好,世界</title> </head> <body> <h1>您好,世界!</h1> <script> document.addEventListener('contextmenu', function () { // 调用在预处理脚本中定义的函数,想法主进程发送信息 elecAPI.showContextMenu() }) </script> </body> </html>