Menu
Class: Menu
创建原生应用菜单和上下文菜单。
进程:主进程
Electron 的内置类不能被用户代码继承。更多信息,请参阅常见问题解答。
new Menu()
创建一个新菜单。
静态方法
Menu
类有以下静态方法:
Menu.setApplicationMenu(menu)
menu
Menu | null
在 macOS 上,将 menu
设置为应用程序菜单。在 Windows 和 Linux 上,menu
将被设置为每个窗口的顶部菜单。
同样在 Windows 和 Linux 上,你可以在顶层项目名称中使用 &
来指示哪个字母应该获得生成的加速键。例如,为文件菜单使用 &File
将会生成一个打开关联菜单的 Alt-F
加速键。按钮标签中指定的字符会带下划线,而 &
字符则不会显示在按钮标签上。
要在项目名称中转义 &
字符,请在其前面再加一个 &
。例如,&&File
会在按钮标签上显示为 &File
。
传入 null
将抑制默认菜单。在 Windows 和 Linux 上,这还有一个额外的效果,即从窗口中移除菜单栏。
如果应用没有设置菜单,默认菜单将会被自动创建。它包含标准项目,如 File
(文件)、Edit
(编辑)、View
(视图)、Window
(窗口)和 Help
(帮助)。
Menu.getApplicationMenu()
返回 Menu | null
- 如果已设置,则返回应用程序菜单;如果未设置,则返回 null
。
返回的 Menu
实例不支持动态添加或移除菜单项。实例属性仍然可以动态修改。
Menu.sendActionToFirstResponder(action)
macOS
action
string
将 action
发送给应用程序的第一个响应者。这用于模拟默认的 macOS 菜单行为。通常你会使用 MenuItem
的 role
属性。
有关 macOS 原生操作的更多信息,请参阅 macOS Cocoa 事件处理指南。
Menu.buildFromTemplate(template)
template
(MenuItemConstructorOptions | MenuItem)[]
返回 Menu
通常,template
是一个用于构造 MenuItem 的 options
数组。用法可参考上文。
你还可以将其他字段附加到 template
的元素上,它们将成为所构造菜单项的属性。
实例方法
menu
对象具有以下实例方法:
menu.popup([options])
在 BaseWindow
中将此菜单作为上下文菜单弹出。
menu.closePopup([window])
window
BaseWindow (可选) - 默认为当前获得焦点的窗口。
关闭 window
中的上下文菜单。
menu.append(menuItem)
menuItem
MenuItem
将 menuItem
追加到菜单末尾。
menu.getMenuItemById(id)
id
string
返回 MenuItem | null
- 具有指定 id
的项目
menu.insert(pos, menuItem)
pos
IntegermenuItem
MenuItem
将 menuItem
插入到菜单的 pos
位置。
实例事件
使用 new Menu
创建或由 Menu.buildFromTemplate
返回的对象会发出以下事件:
某些事件仅在特定操作系统上可用,并已相应标记。
事件:'menu-will-show'
返回
event
Event
当调用 menu.popup()
时发出。
事件:'menu-will-close'
返回
event
Event
当弹出菜单被手动关闭或通过 menu.closePopup()
关闭时发出。
实例属性
menu
对象还具有以下属性:
menu.items
一个包含菜单项的 MenuItem[]
数组。
每个 Menu
由多个 MenuItem
组成,每个 MenuItem
可以有一个子菜单。
示例
一个使用简单模板 API 创建应用程序菜单的示例:
const { app, Menu } = require('electron')
const isMac = process.platform === 'darwin'
const template = [
// { role: 'appMenu' }
...(isMac
? [{
label: app.name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' }
]
}]
: []),
// { role: 'fileMenu' }
{
label: 'File',
submenu: [
isMac ? { role: 'close' } : { role: 'quit' }
]
},
// { role: 'editMenu' }
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
...(isMac
? [
{ role: 'pasteAndMatchStyle' },
{ role: 'delete' },
{ role: 'selectAll' },
{ type: 'separator' },
{
label: 'Speech',
submenu: [
{ role: 'startSpeaking' },
{ role: 'stopSpeaking' }
]
}
]
: [
{ role: 'delete' },
{ type: 'separator' },
{ role: 'selectAll' }
])
]
},
// { role: 'viewMenu' }
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forceReload' },
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
{ role: 'zoomOut' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
]
},
// { role: 'windowMenu' }
{
label: 'Window',
submenu: [
{ role: 'minimize' },
{ role: 'zoom' },
...(isMac
? [
{ type: 'separator' },
{ role: 'front' },
{ type: 'separator' },
{ role: 'window' }
]
: [
{ role: 'close' }
])
]
},
{
role: 'help',
submenu: [
{
label: 'Learn More',
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://electron.js.cn')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
渲染进程
要创建由渲染进程发起的菜单,请使用 IPC 将所需信息发送到主进程,并让主进程代表渲染进程显示菜单。
下面是一个当用户右键单击页面时显示菜单的示例:
// renderer
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
ipcRenderer.send('show-context-menu')
})
ipcRenderer.on('context-menu-command', (e, command) => {
// ...
})
// main
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
})
关于 macOS 应用程序菜单的说明
macOS 的应用程序菜单样式与 Windows 和 Linux 完全不同。以下是一些使你的应用菜单更具原生感的注意事项。
标准菜单
在 macOS 上,有许多系统定义的标准菜单,例如 Services
(服务)和 Windows
(窗口)菜单。要使你的菜单成为标准菜单,你应该将菜单的 role
设置为以下之一,Electron 将会识别它们并使其成为标准菜单:
window
help
services
标准菜单项操作
macOS 为某些菜单项提供了标准操作,例如 About xxx
(关于 xxx)、Hide xxx
(隐藏 xxx)和 Hide Others
(隐藏其他)。要将菜单项的操作设置为标准操作,你应该设置菜单项的 role
属性。
主菜单的名称
在 macOS 上,应用程序菜单的第一个项目的标签总是你的应用名称,无论你设置什么标签。要更改它,请修改你的应用包中的 Info.plist
文件。有关更多信息,请参阅关于信息属性列表文件。
菜单子标签
菜单子标签,或称副标题,可以使用 sublabel
选项添加到菜单项。下面是一个基于上述渲染器示例的例子:
// main
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
sublabel: 'Subtitle 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', sublabel: 'Subtitle 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
})
为特定浏览器窗口设置菜单(Linux Windows)
浏览器窗口的 setMenu
方法可以为特定的浏览器窗口设置菜单。
菜单项位置
在使用 Menu.buildFromTemplate
构建菜单时,你可以利用 before
、after
、beforeGroupContaining
、afterGroupContaining
和 id
来控制项目的放置方式。
before
- 在具有指定 id 的项目之前插入此项目。如果引用的项目不存在,则该项目将被插入到菜单的末尾。这也意味着该菜单项应与引用的项目放在同一个“组”中。after
- 在具有指定 id 的项目之后插入此项目。如果引用的项目不存在,则该项目将被插入到菜单的末尾。这也意味着该菜单项应与引用的项目放在同一个“组”中。beforeGroupContaining
- 为单个上下文菜单提供一种方法,将其所在的组放置在具有指定 id 的项目所在的组之前。afterGroupContaining
- 为单个上下文菜单提供一种方法,将其所在的组放置在具有指定 id 的项目所在的组之后。
默认情况下,除非使用了指定的定位关键字,否则项目将按其在模板中的顺序插入。
示例
模板
[
{ id: '1', label: 'one' },
{ id: '2', label: 'two' },
{ id: '3', label: 'three' },
{ id: '4', label: 'four' }
]
Menu
- 1
- 2
- 3
- 4
模板
[
{ id: '1', label: 'one' },
{ type: 'separator' },
{ id: '3', label: 'three', beforeGroupContaining: ['1'] },
{ id: '4', label: 'four', afterGroupContaining: ['2'] },
{ type: 'separator' },
{ id: '2', label: 'two' }
]
Menu
- 3
- 4
- ---
- 1
- ---
- 2
模板
[
{ id: '1', label: 'one', after: ['3'] },
{ id: '2', label: 'two', before: ['1'] },
{ id: '3', label: 'three' }
]
Menu
- ---
- 3
- 2
- 1