Menu

菜单

创建原生应用菜单和上下文菜单。

进程:主进程

new Menu()

创建新菜单。

静态方法

Menu类有以下方法:

Menu.setApplicationMenu(menu)

  • menu Menu | null

在macOS上将 menu设置成应用内菜单 在windows和Linux上,menu 将会被设置成窗口顶部菜单

在Windows和Linux中,可以在菜单的顶层标签的某个字母前添加&以绑定快捷键。 例如,使用&File后可以使用Alt-F呼出File的子选项。 按钮标签中指定的字符会出现下划线, & 字符不会显示在按钮标签上。

要转义并在项名中显示 & 字符, 可以添加字符 &. 比如, &&File 将在按钮标签上出现 &File

传递 null 值可以禁用默认菜单。 在 Windows 和 Linux 上,使用此方法移除窗口上的菜单栏可能会有额外的效果。

注释:如果应用没有设置菜单的话,系统会生成一个默认菜单。 默认生成的菜单中包含了一些初始选项,例如 文件,编辑, 视图,窗口,帮助

Menu.getApplicationMenu()

返回 Menu | null - 如果有设置, 则返回应用程序菜单, 如果没设置,则返回 null

注释:返回的 Menu实例不支持动态添加或删除菜单项, 但仍然可以动态修改 实例属性

Menu.sendActionToFirstResponder(action) macOS

  • action string

action 发送到应用程序的第一个响应方。 这用于模拟默认的 macOS 菜单行为。 通常你可以使用MenuItemrole属性

有关 macOS 的本地操作的详细信息, 请参阅 macOS Cocoa Event Handling Guide

Menu.buildFromTemplate(template)

  • template (MenuItemConstructorOptions | MenuItem)[]

返回 Menu

一般来说, template是一个options类型的数组,用于构建MenuItem。 使用方法可参考前文。

您还可以将其他字段附加到template,它们将成为菜单项的属性。

实例方法

menu 对象具有以下实例方法:

menu.popup([options])

  • options Object (可选)
    • window BrowserWindow (可选) - 默认为选中窗口.
    • x number (可选) - 默认为当前鼠标的位置。 如果指定了y,则该选项必选。
    • y number (可选) - 默认为当前鼠标的位置。 如果指定了x,则该选项必选。
    • positioningItem number (可选) macOS - 在指定鼠标光标下定位的菜单项的索引。 默认值为 -1。
    • sourceType string (optional) Windows Linux - This should map to the menuSourceType provided by the context-menu event. It is not recommended to set this value manually, only provide values you receive from other APIs or leave it undefined. Can be none, mouse, keyboard, touch, touchMenu, longPress, longTap, touchHandle, stylus, adjustSelection, or adjustSelectionReset.
    • callback Function (optional) - 会在菜单关闭后被调用.

弹出此菜单作为上下文菜单在 BrowserWindow

menu.closePopup([browserWindow])

关闭 browserWindow 中的上下文菜单。

menu.append(menuItem)

menuItem 追加到菜单。

menu.getMenuItemById(id)

  • id 字符串

返回具有指定id项的MenuItem | null

menu.insert(pos, 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 [] 数组。

每个 菜单 由多个 MenuItem 组成, 每个 MenuItem可以有子菜单。

示例

使用简单模板API创建 application menu 的示例代码:

  1. const { app, Menu } = require('electron')
  2. const isMac = process.platform === 'darwin'
  3. const template = [
  4. // { role: 'appMenu' }
  5. ...(isMac
  6. ? [{
  7. label: app.name,
  8. submenu: [
  9. { role: 'about' },
  10. { type: 'separator' },
  11. { role: 'services' },
  12. { type: 'separator' },
  13. { role: 'hide' },
  14. { role: 'hideOthers' },
  15. { role: 'unhide' },
  16. { type: 'separator' },
  17. { role: 'quit' }
  18. ]
  19. }]
  20. : []),
  21. // { role: 'fileMenu' }
  22. {
  23. label: 'File',
  24. submenu: [
  25. isMac ? { role: 'close' } : { role: 'quit' }
  26. ]
  27. },
  28. // { role: 'editMenu' }
  29. {
  30. label: 'Edit',
  31. submenu: [
  32. { role: 'undo' },
  33. { role: 'redo' },
  34. { type: 'separator' },
  35. { role: 'cut' },
  36. { role: 'copy' },
  37. { role: 'paste' },
  38. ...(isMac
  39. ? [
  40. { role: 'pasteAndMatchStyle' },
  41. { role: 'delete' },
  42. { role: 'selectAll' },
  43. { type: 'separator' },
  44. {
  45. label: 'Speech',
  46. submenu: [
  47. { role: 'startSpeaking' },
  48. { role: 'stopSpeaking' }
  49. ]
  50. }
  51. ]
  52. : [
  53. { role: 'delete' },
  54. { type: 'separator' },
  55. { role: 'selectAll' }
  56. ])
  57. ]
  58. },
  59. // { role: 'viewMenu' }
  60. {
  61. label: 'View',
  62. submenu: [
  63. { role: 'reload' },
  64. { role: 'forceReload' },
  65. { role: 'toggleDevTools' },
  66. { type: 'separator' },
  67. { role: 'resetZoom' },
  68. { role: 'zoomIn' },
  69. { role: 'zoomOut' },
  70. { type: 'separator' },
  71. { role: 'togglefullscreen' }
  72. ]
  73. },
  74. // { role: 'windowMenu' }
  75. {
  76. label: 'Window',
  77. submenu: [
  78. { role: 'minimize' },
  79. { role: 'zoom' },
  80. ...(isMac
  81. ? [
  82. { type: 'separator' },
  83. { role: 'front' },
  84. { type: 'separator' },
  85. { role: 'window' }
  86. ]
  87. : [
  88. { role: 'close' }
  89. ])
  90. ]
  91. },
  92. {
  93. role: 'help',
  94. submenu: [
  95. {
  96. label: 'Learn More',
  97. click: async () => {
  98. const { shell } = require('electron')
  99. await shell.openExternal('https://electronjs.org')
  100. }
  101. }
  102. ]
  103. }
  104. ]
  105. const menu = Menu.buildFromTemplate(template)
  106. Menu.setApplicationMenu(menu)

渲染进程

要创建由渲染器启动的菜单,请通过 IPC 发送所需的信息到主过程,并让主过程代替渲染器显示菜单。

以下是用户右键单击页面时显示菜单的示例:

  1. // renderer
  2. window.addEventListener('contextmenu', (e) => {
  3. e.preventDefault()
  4. ipcRenderer.send('show-context-menu')
  5. })
  6. ipcRenderer.on('context-menu-command', (e, command) => {
  7. // ...
  8. })
  9. // main
  10. ipcMain.on('show-context-menu', (event) => {
  11. const template = [
  12. {
  13. label: 'Menu Item 1',
  14. click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
  15. },
  16. { type: 'separator' },
  17. { label: 'Menu Item 2', type: 'checkbox', checked: true }
  18. ]
  19. const menu = Menu.buildFromTemplate(template)
  20. menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
  21. })

MacOS中应用菜单注意事项

macOS 相比于 Windows 和 Linux 有着完全不同的应用程序菜单。 以下是一些有关使应用菜单更像原生应用菜单的注意事项。

标准菜单

MacOS有一些系统预定义的菜单,像是Services and Windows。 让你的菜单更像MacOS标准菜单,只需设置菜单role值为如下示之一,Electron便会自动认出并设置成标准菜单,:

  • window
  • help
  • services

标准菜单项操作

macOS 已经为某些菜单项提供了标准操作, 如 about xxxHide xxxHide Others。 若要将菜单项的操作设置为标准操作, 应设置菜单项的 role 属性。

主菜单的名称

在 macOS 中应用程序菜单的第一个项目的标签总是你的应用程序的名字, 无论你设置什么标签。 如要更改它, 请修改应用程序包的 Info. plist 文件。 详情参阅:About Information Property List Files

设置特定浏览器窗口的菜单 ( Linux Windows )

浏览器窗口的 setMenu 方法 可以设置特定浏览器窗口的菜单

菜单项位置

你可以使用 before, after, beforeGroupContaining, afterGroupContainingid 来控制由 Menu.buildFromTemplate 生成的菜单项的位置.

  • before - 在指定的标签之前插入菜单项。 如果引用值不存在,那么该菜单项会插在这个菜单的尾部。 这还意味着,菜单项应该被放置在与引用项相同的组中。
  • after - 在指定的标签之后插入菜单项。 如果引用值不存在,那么该菜单项会插在这个菜单的尾部。 这还意味着,菜单项应该被放置在与引用项相同的组中。
  • beforeGroupContaining - 为单个上下文菜单提供一种方法,用于在具有指定标签项的包含组之前声明其包含组的位置
  • afterGroupContaining - 为单个上下文菜单提供一种方法,用于在具有指定标签项的包含组之后声明其包含组的位置

默认情况下,除非有位置相关的属性,所有的菜单项会按照模板中的顺序排放。

示例

模板:

  1. [
  2. { id: '1', label: 'one' },
  3. { id: '2', label: 'two' },
  4. { id: '3', label: 'three' },
  5. { id: '4', label: 'four' }
  6. ]

菜单:

  1. - 1
  2. - 2
  3. - 3
  4. - 4

模板:

  1. [
  2. { id: '1', label: 'one' },
  3. { type: 'separator' },
  4. { id: '3', label: 'three', beforeGroupContaining: ['1'] },
  5. { id: '4', label: 'four', afterGroupContaining: ['2'] },
  6. { type: 'separator' },
  7. { id: '2', label: 'two' }
  8. ]

菜单:

  1. - 3
  2. - 4
  3. - ---
  4. - 1
  5. - ---
  6. - 2

模板:

  1. [
  2. { id: '1', label: 'one', after: ['3'] },
  3. { id: '2', label: 'two', before: ['1'] },
  4. { id: '3', label: 'three' }
  5. ]

菜单:

  1. - ---
  2. - 3
  3. - 2
  4. - 1