菜单

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

进程:主进程

new Menu()

创建新菜单。

静态方法

Menu类有以下方法:

Menu.setApplicationMenu(menu)

  • menu Menu | null

Sets menu as the application menu on macOS. On Windows and Linux, the menu will be set as each window’s top menu.

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

Passing null will suppress the default menu. On Windows and Linux, this has the additional effect of removing the menu bar from the window.

Note: The default menu will be created automatically if the app does not set one. 默认生成的菜单中包含了一些初始选项,例如 文件,编辑, 视图,窗口,帮助

Menu.getApplicationMenu()

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

Note: The returned Menu instance doesn’t support dynamic addition or removal of menu items. 但仍然可以动态修改 实例属性

Menu.sendActionToFirstResponder(action) macOS

  • action String

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

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

Menu.buildFromTemplate(template)

  • template (MenuItemConstructorOptions | MenuItem)[]

返回 Menu

Generally, the template is an array of options for constructing a MenuItem. The usage can be referenced above.

You can also attach other fields to the element of the template and they will become properties of the constructed menu items.

实例方法

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

menu.popup([options])

  • options Object (optional)
    • window BrowserWindow (可选) - 默认为选中窗口.
    • x Number (optional) - Default is the current mouse cursor position. Must be declared if y is declared.
    • y Number (optional) - Default is the current mouse cursor position. Must be declared if x is declared.
    • positioningItem Number (optional) macOS - The index of the menu item to be positioned under the mouse cursor at the specified coordinates. Default is -1.
    • callback Function (optional) - 会在菜单关闭后被调用.

将此菜单作为 browserWindow 中的上下文菜单弹出。

menu.closePopup([browserWindow])

关闭 browserWindow 中的上下文菜单。

menu.append(menuItem)

menuItem 追加到菜单。

menu.getMenuItemById(id)

  • id String

返回具有指定id项的MenuItem

menu.insert(pos, menuItem)

menuItem 插入菜单的 pos 位置。

实例事件

Objects created with new Menu or returned by Menu.buildFromTemplate emit the following events:

注意: 某些事件仅在特定的操作系统上可用, 这些方法会被标记出来。

事件: ‘menu-will-show’

返回:

  • event Event

调用menu.popup()事件时触发该事件。

事件: ‘menu-will-close’

返回:

  • event Event

手动关闭弹出,或使用 menu.closePopup()方法关闭弹出时,触发该事件。

实例属性

menu 对象还具有以下属性:

menu.items

包含菜单项的 MenuItem [] 数组。

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

示例

Menu 仅在主进程( main process)中可用, 但您也可以在渲染进程(render process)中通过 remote 模块使用它。

主进程

在主进程中创建程序菜单的简单API模版示例:

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

渲染进程

下面是通过 remote 模块在网页(render process)中动态创建右击菜单的示例:

  1. <!-- index.html -->
  2. <script>
  3. const { remote } = require('electron')
  4. const { Menu, MenuItem } = remote
  5. const menu = new Menu()
  6. menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
  7. menu.append(new MenuItem({ type: 'separator' }))
  8. menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
  9. window.addEventListener('contextmenu', (e) => {
  10. e.preventDefault()
  11. menu.popup({ window: remote.getCurrentWindow() })
  12. }, false)
  13. </script>

MacOS中应用菜单注意事项

macOS has a completely different style of application menu from Windows and Linux. Here are some notes on making your app’s menu more native-like.

标准菜单

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

  • window
  • help
  • services

标准菜单项操作

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

主菜单的名称

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

Setting Menu for Specific Browser Window (Linux Windows)

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

菜单项位置

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

  • before - 在指定的标签之前插入菜单项。 如果引用值不存在,那么该菜单项会插在这个菜单的尾部。 这还意味着,菜单项应该被放置在与引用项相同的组中。

  • after - 在指定的标签之后插入菜单项。 如果引用值不存在,那么该菜单项会插在这个菜单的尾部。 这还意味着,菜单项应该被放置在与引用项相同的组中。

  • beforeGroupContaining - Provides a means for a single context menu to declare the placement of their containing group before the containing group of the item with the specified label.

  • afterGroupContaining - Provides a means for a single context menu to declare the placement of their containing group after the containing group of the item with the specified label.

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

示例

模板:

  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