菜单

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

进程:主进程

new Menu()

创建新菜单。

静态方法

menu类有以下静态方法:

Menu.setApplicationMenu(menu)

  • menu Menu | null
    当在MacOS、Windows、Linux中使用menu设置程序菜单时,会设置在各个程序窗体的顶层。

在windows和Linux系统中,使用null参数将会移除菜单栏, 但在MacOS系统中则不会有任何效果;

注意:这个API调用要在程序的ready事件模块之后;

Menu.getApplicationMenu()

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

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

Menu.sendActionToFirstResponder(action) macOS

  • action String
    action 发送到应用程序的第一个响应方。 这用于模拟默认的 macOS 菜单行为。 Usually you would use the role property of a MenuItem.

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

Menu.buildFromTemplate(template)

  • template MenuItemConstructorOptions[]
    返回 Menu

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

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

实例方法

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

menu.popup(options)

  • options Object (可选)

    • window BrowserWindow (可选) - 默认为选中窗口.
    • x 数字 (可选)-默认值是当前鼠标光标的位置。如果声明了 y, 则必须声明。
    • y 数字 (可选)-默认值是当前鼠标光标的位置。如果声明了 x, 则必须声明。
    • positioningItem数字 (可选) macOS -要在指定坐标下的鼠标光标下定位的菜单项的索引。默认值为-1。
    • callback Function (optional) - 会在菜单关闭后被调用.
      将此菜单作为 browserWindow 中的上下文菜单弹出。

menu.closePopup([browserWindow])

  • browserWindow BrowserWindow (可选) - 默认为选中窗口.
    关闭 browserWindow 中的上下文菜单。

menu.append(menuItem)

  • menuItem 菜单项
    menuItem 追加到菜单。

menu.getMenuItemById(id)

  • id String
    返回具有指定id项的MenuItem

menu.insert(pos, menuItem)

  • pos Integer
  • menuItem 菜单项
    menuItem 插入菜单的 pos 位置。

实例事件

new Menu 创建的对象触发以下事件:

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

事件: 'menu-will-show'

返回:

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

事件: 'menu-will-close'

返回:

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

实例属性

menu 对象还具有以下属性:

menu.items

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

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

实例事件

使用 new Menu方法创建的对象,或者Menu.buildFromTemplate返回的对象都会触发以下事件:

示例

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

主进程

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

  1. const { app, Menu } = require('electron')
  2. const template = [
  3. {
  4. label: 'Edit',
  5. submenu: [
  6. { role: 'undo' },
  7. { role: 'redo' },
  8. { type: 'separator' },
  9. { role: 'cut' },
  10. { role: 'copy' },
  11. { role: 'paste' },
  12. { role: 'pasteandmatchstyle' },
  13. { role: 'delete' },
  14. { role: 'selectall' }
  15. ]
  16. },
  17. {
  18. label: 'View',
  19. submenu: [
  20. { role: 'reload' },
  21. { role: 'forcereload' },
  22. { role: 'toggledevtools' },
  23. { type: 'separator' },
  24. { role: 'resetzoom' },
  25. { role: 'zoomin' },
  26. { role: 'zoomout' },
  27. { type: 'separator' },
  28. { role: 'togglefullscreen' }
  29. ]
  30. },
  31. {
  32. role: 'window',
  33. submenu: [
  34. { role: 'minimize' },
  35. { role: 'close' }
  36. ]
  37. },
  38. {
  39. role: 'help',
  40. submenu: [
  41. {
  42. label: 'Learn More',
  43. click () { require('electron').shell.openExternal('https://electronjs.org') }
  44. }
  45. ]
  46. }
  47. ]
  48. if (process.platform === 'darwin') {
  49. template.unshift({
  50. label: app.getName(),
  51. submenu: [
  52. { role: 'about' },
  53. { type: 'separator' },
  54. { role: 'services' },
  55. { type: 'separator' },
  56. { role: 'hide' },
  57. { role: 'hideothers' },
  58. { role: 'unhide' },
  59. { type: 'separator' },
  60. { role: 'quit' }
  61. ]
  62. })
  63. // Edit menu
  64. template[1].submenu.push(
  65. { type: 'separator' },
  66. {
  67. label: 'Speech',
  68. submenu: [
  69. { role: 'startspeaking' },
  70. { role: 'stopspeaking' }
  71. ]
  72. }
  73. )
  74. // Window menu
  75. template[3].submenu = [
  76. { role: 'close' },
  77. { role: 'minimize' },
  78. { role: 'zoom' },
  79. { type: 'separator' },
  80. { role: 'front' }
  81. ]
  82. }
  83. const menu = Menu.buildFromTemplate(template)
  84. 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中的应用程序有着和windows,linux完全不同风格的菜单样式。这里有一些说明,可以让你的程序菜单看起来更贴合原生系统。

标准菜单

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

  • window
  • help
  • services

标准菜单项操作

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

主菜单的名称

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

设置特定浏览器窗口的菜单 ( 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. <br />- 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. <br />- 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. <br />- ---
  2. - 3
  3. - 2
  4. - 1