Electron 菜單Menu的使用


菜單

創建原生應用菜單和上下文菜單。

進程:主進程

new Menu()

創建新菜單。

靜態方法

Menu類有以下方法:

  • menu Menu | null

在macOS上將 menu設置成應用內菜單

在windows和Linux上,menu 將會被設置成窗口頂部菜單

在Windows和Linux中,可以在菜單的頂層標簽的某個字母前添加&以綁定快捷鍵。 例如,使用&File后可以使用Alt-F呼出File的子選項。 被綁定快捷鍵的字母將會以下划線標出。 &並不會在運行時顯示

傳遞 null 值可以禁用默認菜單。 在 Windows 和 Linux 上,使用此方法移除窗口上的菜單欄可能會有額外的效果。

注釋:如果應用沒有設置菜單的話,系統會生成一個默認菜單。 默認生成的菜單中包含了一些初始選項,例如 文件,編輯, 視圖,窗口,幫助

EN

返回 Menu | null - 如果有設置, 則返回應用程序菜單, 如果沒設置,則返回 null

注釋:返回的 Menu實例不支持動態添加或刪除菜單項, 但仍然可以動態修改 實例屬性

EN

  • action String

action 發送到應用程序的第一個響應方。 這用於模擬默認的 macOS 菜單行為。 通常你可以使用MenuItemrole屬性

有關 macOS 的本地操作的詳細信息, 請參閱 macOS Cocoa Event Handling Guide

EN

  • template (MenuItemConstructorOptions | MenuItem)[]

返回 Menu

一般來說, template是一個options類型的數組,用於構建MenuItem。 使用方法可參考前文。

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

實例方法

menu 對象具有以下實例方法:

  •   options
    

    Object (可選)

    • window BrowserWindow (可選) - 默認為選中窗口.
    • x Number (可選) - 默認為當前鼠標的位置。 如果指定了y,則該選項必選。
    • y Number (可選) - 默認為當前鼠標的位置。 如果指定了x,則該選項必選。
    • positioningItem Number (optional) macOS - The index of the menu item to be positioned under the mouse cursor at the specified coordinates. 默認值為 -1。
    • callback Function (optional) - 會在菜單關閉后被調用.

將此菜單作為 browserWindow 中的上下文菜單彈出。

menu.closePopup([browserWindow])

關閉 browserWindow 中的上下文菜單。

menuItem 追加到菜單。

  • id String

Returns MenuItem | null the item with the specified id

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 對象還具有以下屬性:

包含菜單項的 MenuItem [] 數組。

每個 菜單 由多個 MenuItem 組成, 每個 MenuItem 可以有子菜單。

菜單項

添加菜單項到應用程序菜單和上下文菜單中

進程:主進程

有關示例, 請參見 Menu

new MenuItem(可選)

  •   選項
    

    對象

    •   click
      

      功能(可選)-

      click(menuItem, browserWindow, event)
      

      單擊菜單項時將調用。

    • role字符串(可選) -可以是undoredocutcopypastepasteAndMatchStyledeleteselectAllreloadforceReloadtoggleDevToolsresetZoomzoomInzoomOuttogglefullscreenwindowminimizeclosehelpaboutserviceshidehideOthersunhidequitstartSpeakingstopSpeakingzoomfrontappMenufileMenueditMenuviewMenurecentDocumentstoggleTabBarselectNextTabselectPreviousTabmergeAllWindowsclearRecentDocumentsmoveTabToNewWindowwindowMenu-定義菜單項的動作,當指定該click屬性時將被忽略。見角色

    • typeString (可選)-可以是 normalseparatorsubmenucheckboxradio

    • label String (可選)

    • sublabel String (可選)

    • toolTip字符串(可選)macOS-懸停此菜單項的文本。

    • accelerator Accelerator (可選)

    • icon (NativeImage | String) (可選)

    • enabled Boolean (可選) - 如果為 false,該菜單項將會置灰且不可點擊。

    • acceleratorWorksWhenHidden布爾值(可選)macOS-默認為true,當false項目不可見時,將阻止加速器觸發該項目。

    • visibleBoolean (可選)-如果為 false, 該菜單項將完全隱藏。

    • checkedBoolean (可選)-只應為 checkboxradio 類型菜單項指定。

    • registerAccelerator布爾值(可選)Linux Windows-如果為false,則不會在系統中注冊加速器,但仍會顯示該加速器。默認值true。

    • submenu (MenuItemConstructorOptions[] | Menu) (optional) - Should be specified for submenu type menu items. If submenu is specified, the type: 'submenu' can be omitted. 如果該值不屬於Menu,它將被函數Menu.buildFromTemplate自動轉換。

    • id字符串(可選)-在單個菜單中唯一。如果已定義,則可以通過position屬性將其用作對此項目的引用。

    • beforeString [](可選)-將此項目插入具有指定標簽的項目之前。如果所引用的項目不存在,則該項目將插入菜單的末尾。還意味着所討論的菜單項應與該菜單項位於同一“組”中。

    • after String[] (optional) - Inserts this item after the item with the specified label. 如果引用值不存在,那么該菜單項會插在這個菜單的尾部。

    • beforeGroupContaining String [](可選)-為單個上下文菜單提供一種方法,以聲明其包含組在具有指定標簽的項目的包含組之前的位置。

    • afterGroupContaining String [](可選)-為單個上下文菜單提供一種方法,以聲明其包含組在具有指定標簽的項目的包含組之后的位置。

注意: acceleratorWorksWhenHidden只在MacOS中生效,因為在Windows和Linux中快捷鍵不會隨着隱藏菜單項而失效。 該選項讓用戶可以選擇關閉,因為這是本地 macOS 開發中的可能。 此屬性只能在macOS High Sierra 10.13或以上中使用。

角色

可以通過角色來為menu添加預定義行為。

最好給任何一個菜單指定 role去匹配一個標准角色, 而不是嘗試在 click 函數中手動實現該行為。 內置的 role 行為將提供最佳的原生體驗。

使用 role 時, labelaccelerator 值是可選的, 並為每個平台,將默認為適當值。

每個菜單項必須有一個rolelabel或在分離器的情況下type

role 屬性可以具有以下值:

  • undo
  • about -觸發本機“關於”面板(Window上的自定義消息框,不提供其自身的框)。
  • redo
  • cut
  • copy
  • paste
  • pasteAndMatchStyle
  • selectAll
  • delete
  • minimize - 最小化當前窗口。
  • close - 關閉當前窗口.
  • quit - 退出程序
  • reload - 重新加載當前窗口。
  • forcereload - 忽略緩存,重新加載當前窗口。
  • toggledevtools - 在當前窗口中隱藏/顯示開發者工具。
  • togglefullscreen - 將當前窗口切換至全屏模式。
  • resetzoom - 將主頁的縮放級別重置為初始大小.
  • zoomin - 主頁面放大 10%.
  • zoomout -主頁面縮小 10%.
  • fileMenu -整個默認的“文件”菜單(關閉/退出)
  • editMenu-默認的 "編輯" 菜單 (包括撤消、復制等)
  • viewMenu -整個默認的“查看”菜單(重新加載,切換開發者工具等)
  • windowMenu -整個默認的“窗口”菜單(最小化,縮放等)。

以下附加角色在macOS上可用:

  • appMenu -整個默認的“應用”菜單(關於,服務等)
  • hide-映射到 hide 操作.
  • hideOthers-映射到 hideOtherApplications 操作.
  • unhide-映射到 unhideAllApplications 操作.
  • startSpeaking-映射到 startSpeaking 操作.
  • stopSpeaking-映射到 stopSpeaking 操作.
  • front-映射到 arrangeInFront 操作.
  • zoom-映射到 performZoom 操作.
  • toggleTabBar-映射到 toggleTabBar 操作.
  • selectNextTab - 映射到 selectNextTab 操作.
  • selectPreviousTab - 映射到 selectPreviousTab 操作.
  • mergeAllWindows - 映射到 mergeAllWindows 操作.
  • moveTabToNewWindow - 映射到 moveTabToNewWindow 操作.
  • window - 這個子菜單是"Window" 菜單.
  • help-這個子菜單是 "Help" 菜單.
  • services-子菜單是“服務”菜單。這僅適用於在應用程序菜單使用,是一樣的MacOS應用程序上下文菜單中使用的“服務”子菜單,這是不是在電子實現。
  • recentDocuments-這個子菜單是 "Open Recent" 菜單.
  • clearRecentDocuments -映射到 clearRecentDocuments 操作.

在 macOS 上指定 role 時, labelaccelerator 是影響菜單項的唯一選項。 所有其它選項都將被忽略。 不過,仍然支持小寫的role,如toggledevtools

諾塔Bene的:enabledvisibility屬性不可用於在MacOS托盤頂級菜單項。

實例屬性

以下為 MenuItem 實例的可用屬性:

String 指定了該選項唯一的id,此屬性可被動態更改。

一個String指示項目的可見標簽。

當 MenuItem 接收到 click 事件時激發的Function. It can be called with menuItem.click(event, focusedWindow, focusedWebContents).

一個Menu(可選)包含菜單項的子菜單(如果有)。

String 表示菜單項的類型 Can be normal, separator, submenu, checkbox or radio.

String`(可選) 指出菜單項的角色 Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu

一個Accelerator(可選)指示項目的加速器(如果已設置)。

A NativeImage | String(可選),指示項目的圖標(如果已設置)。

一個String指示項目的子標簽。

一個String指示項目的懸停文本。

一個 Boolean 類型的值, 指示是否啟用該項, 該屬性可以動態改變

一個 Boolean 類型的值, 指示該項是否可見, 該屬性可以動態改變。

一個 Boolean 類型的值, 指示是否選中該項, 該屬性可以動態改變。

checkbox 菜單項將在選中時切換 checked 的開關屬性。

單選菜單項 將返回單擊時checked屬性, 並將關閉同一菜單中所有相鄰項的屬性。

你可以為其他行為添加click函數。

一個Boolean指示是否加速器應與系統進行注冊,或只是顯示。

此屬性可以動態更改。

一個Number指示項目的順序唯一ID。

Menu該項目所屬的A。

示例

Menu 僅在主進程( main process)中可用, 但您也可以在渲染進程(render process)中通過 remote 模塊使用它。

主進程

在主進程中創建程序菜單的簡單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://electronjs.org')
        }
      }
    ]
  }
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)

渲染進程

下面是通過 remote 模塊在網頁(render process)中動態創建右擊菜單的示例:

<!-- index.html -->
<script>
const { remote } = require('electron')
const { Menu, MenuItem } = remote

const menu = new Menu()
menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
menu.append(new MenuItem({ type: 'separator' }))
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))

window.addEventListener('contextmenu', (e) => {
  e.preventDefault()
  menu.popup({ window: remote.getCurrentWindow() })
}, false)
</script>

MacOS中應用菜單注意事項

macOS 相比於 Windows 和 Linux 有着完全不同的應用程序菜單。 以下是一些有關使應用菜單更像原生應用菜單的注意事項。

標准菜單

MacOS有一些系統預定義的菜單,像是Services and Windows。 讓你的菜單更像MacOS標准菜單,只需設置菜單role值為如下示之一,Electron便會自動認出並設置成標准菜單,:

  • window
  • help
  • services

標准菜單項操作

macOS 已經為某些菜單項提供了標准操作, 如 about xxx Hide xxxHide 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.

默認情況下,除非有位置相關的屬性,所有的菜單項會按照模板中的順序排放。

示例

模板:

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

菜單:

- 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' }
]

菜單:

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

模板:

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

菜單:

- ---
- 3
- 2
- 1

案例

在主進程中渲染菜單

主進程

//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 electron 包導入了 app 和 BrowserWindow 模塊 。
const { app, BrowserWindow,Menu } = require('electron')

//在此之后,你定義了一個創建 新的瀏覽窗口的函數並將 nodeIntegration 設置為 true,將 index.html 文件加載到窗口中(第 12 行,稍后我們將討論該文件)
function createWindow () {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            //是否注入nodeapi
            nodeIntegration: true,
            //渲染進程是否啟用remote模塊
            enableRemoteModule: true
        }
    })

    win.loadFile('index.html')

}
//你通過調用 createWindow方法,在 electron app 第一次被初始化時創建了一個新的窗口。
app.whenReady().then(createWindow)

//您添加了一個新的偵聽器,當應用程序不再有任何打開窗口時試圖退出。 由於操作系統的 窗口管理行為 ,此監聽器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

//您添加一個新的偵聽器,只有當應用程序激活后沒有可見窗口時,才能創建新的瀏覽器窗口。 例如,在首次啟動應用程序后或重啟運行中的應用程序
app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
        createWindow()
    }
})

//5s后
setTimeout(()=>{
    //menu item
    const template = [
        {label: "第一個菜單項目"},
        {label: "第二個菜單項目"},
        {role: "undo"},
        {type: 'separator'},
        {label: "第三個菜單項目"},
        {label: "第四個菜單項目"},
    ];
    //使用 menu item 創建menu對象
    const menu = Menu.buildFromTemplate(template);
    //設置菜單
    Menu.setApplicationMenu(menu);
    //彈出菜單
    menu.popup();
}, 5000)

渲染進程

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>菜單</title>
</head>
<body>
<h1>菜單</h1>
</body>
</html>

效果

image-20210204162036741

渲染進程中使用菜單並注冊點擊事件使用MenuItem

渲染進程

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>菜單</title>
</head>
<body>
<h1>菜單</h1>
<button onclick="openMenu()">點擊彈出菜單</button>
</body>
<script>
    const { Menu, MenuItem } = require('electron').remote
    function openMenu() {
        //menu item
        const template = [
            {label: "第一個菜單項目"},
            {label: "第二個菜單項目"},
            {role: "undo"},
            {type: 'separator'},
            {label: "第三個菜單項目"},
            {label: "第四個菜單項目"},
            {label: "點擊測試", click : () => {
                    console.log('點擊事件觸發.....');
                }
            },
        ];
        //使用 menu item 創建menu對象
        const menu = Menu.buildFromTemplate(template);
        //設置成應用菜單
        //Menu.setApplicationMenu(menu);

        //使用MenuItem
        let item = new MenuItem({label : '這是MenuItem'});

        menu.append(item);
        //彈出菜單
        menu.popup();
    }
</script>
</html>

image-20210204163948018

渲染進程中創建帶子菜單的菜單

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>菜單</title>
</head>
<body>
<h1>菜單</h1>
<button onclick="openMenu()">點擊彈出菜單</button>
</body>
<script>
    const { Menu, MenuItem } = require('electron').remote
    function openMenu() {
        //menu item
        const template = [
            {label: "第一個菜單項目"},
            {label: "第二個菜單項目"},
            {role: "undo"},
            {type: 'separator'},
            {label: "第三個菜單項目"},
            {label: "第四個菜單項目"},
            {label: "點擊測試", click : () => {
                    console.log('點擊事件觸發.....');
                }
            },
            new MenuItem({label : '這是子菜單測試', submenu:[
                    {label: '子菜單1'},
                    {label: '子菜單2'},
                    {label: '子菜單3'}
                ]})
        ];
        //使用 menu item 創建menu對象
        const menu = Menu.buildFromTemplate(template);
        //設置成應用菜單
        //Menu.setApplicationMenu(menu);

        //使用MenuItem
        let item = new MenuItem({label : '這是MenuItem'});

        menu.append(item);
        //彈出菜單
        menu.popup();
    }
</script>
</html>

image-20210204164458769


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM