4
头图

In Electron, you can use html to develop the content displayed in it, and some menus can also be drawn in html form. You can call the relevant api when you click it. Although the construction is convenient, the style can be adjusted arbitrarily. But it is actually a simulated menu, not a native menu of the application. This simulated menu has the following shortcomings:

  • html simulation generation, non-native.
  • Each function needs to be called or implemented by its own code, and the actual native menu has many preset behaviors that can be used directly.
  • The menu simulated in Mac and Linux cannot be displayed in the top menu bar.
  • The html simulation menu cannot generate the system tray menu.

The following will introduce the native menu in Electron.

Menu type

There are three types of menus in Electron: application menu, context menu and tray menu.

Application menu

The application menu is the menu above the application.

Only one array is needed to construct the menu, where each member is a menu item, and each menu item has some specified configuration. Take the following code as an example:

const myMenuTemplate = [
  {
    // 设置菜单项文本
    label: '文件',
    // 设置子菜单
    submenu: [
      {
        label: '关于 Electron',
        // 设置菜单角色
        role: 'about', // about (关于),此值只针对 Mac  OS X 系统
        // 点击事件 role 属性能识别时 点击事件无效
        click: () => {
          var aboutWin = new BrowserWindow({ width: 300, height: 200, parent: win, modal: true });
          aboutWin.loadFile('about.html');
        }
      },
      {
        // 设置菜单的类型是分隔栏
        type: 'separator'
      },
      {
        label: '关闭',
        // 设置菜单的热键
        accelerator: 'Command+Q',
        click: () => {
          win.close();
        }
      }
    ]
  },
  {
    label: '编辑',
    submenu: [
      {
        label: '复制',
        click: () => {
          win.webContents.insertText('复制');
        }
      },
      {
        label: '剪切',
        click: () => {
          win.webContents.insertText('剪切');
        }
      },
      {
        type: 'separator'
      },
      {
        label: '查找',
        accelerator: 'Command+F',
        click: () => {
          win.webContents.insertText('查找');
        }
      },
      {
        label: '替换',
        accelerator: 'Command+R',
        click: () => {
          win.webContents.insertText('替换');
        }
      }
    ]
  }
];

The above is the configuration of a menu. Commonly used configurations are as follows:

For more menu item configuration, please refer to menu item

To apply the menu, you must use the Menu class, and its definition is placed in the electron namespace. Menu class has the following two static methods for generating and applying menus

  • buildFromTemplate(menuTpl /* menu menu configuration*/) is used to generate a menu instance according to the menu configuration, the return value is the menu object, which can be replaced by new Menu()
  • setApplicationMenu(menu /* menu object*/) method uses it as the application menu.

Load the file and apply the menu code as follows:

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const Menu = electron.Menu;

function createWindow() {
  win = new BrowserWindow({ file: 'index.html' });
  win.loadFile('./index.html');
  // 应用上面准备好的菜单配置生成
  const template = myMenuTemplate;
  //  创建菜单对象
  const menu = Menu.buildFromTemplate(template);
  //  设置应用菜单
  Menu.setApplicationMenu(menu);
  win.on('closed', () => {
    console.log('closed');
    win = null;
  });
}
app.on('ready', createWindow);
app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});

Based on the above code, the following effects can be seen under the window:

43385-uicw6dsf0r.png

59942-hz1loyr540c.png

The effect is as follows under Mac:

39324-03jzp4pdn385.png

08127-2spol8owt9g.png

Our custom effect under window:

52577-h8kngdc6u8r.png

And about under Mac is provided directly by the system:

31156-n5mu3vo79ad.png

renderings

Obviously, it is just like the configuration under the window, but it is obviously different on the Mac. The first file menu is missing, and there are two more menu items in the editor.

This is a characteristic of the Mac system itself. The text display of the first menu under the Mac must be the name of the application. Here it is started with the electron command, so it is electron. It can be understood that the first menu item configuration label under Mac is invalid. (Think about your Mac’s first menu, most of which are application names, such as Safri, PhotoShop CC)

If you have obsessive-compulsive disorder, you must modify the Info.plist file of the application package that needs to be modified, please refer to About Information Property List Files

The above is the form of the default configuration application menu, but in actual scenes, there is often a need to dynamically adjust the menu. For example, a certain menu is unavailable in certain states, and there is an additional menu when entering a certain state. At this time, we need Ability to adjust the availability or visibility of menu items and provide the ability to dynamically add new menus.

There are the following related configurations to adjust the status of the menu items:

  • menuItem.enabled Boolean value identifies whether the menu item is enabled or not.
  • menuItem.visible Boolean value indicates whether the menu item is visible.
  • menuItem.checked Boolean value indicates whether the menu item is selected.

To obtain a menu item, you can use the getMenuItemById(id) method on the menu object. This method will return the corresponding menu item and adjust the relevant attributes of the menu item.

To add a new menu item, you can first use new MenuItem() build a menu item, and then call the following method of the menu instance to insert it:

  • menu.append(menuItem) adds a menu to the menu.
  • menu.insert(pos, menuItem) Add a new menu item at the specified position in the menu

Under windows, click to switch display and switch to enable the effect as follows:

28059-gvpbyjh1s58.png

The new effects are as follows:

72478-tkf3y5rsupa.png

Switching and new effects in mac:

98518-hoifqg0fy5.png

Context menu

The context menu is the right-click menu of the mouse. The method of constructing the menu is the same as that mentioned in the application menu above, which is generated through the configuration array of menu items. However, to make it into a context menu, you no longer need to use the setApplicationMenu() method. You only need to build the menu, then listen to the contextmenu event, and call popup({x,y}) to display the menu at the specified location.

Examples of incomplete code are as follows:

const menu = new Menu( /* 菜单配置数组*/ );
document.getElementById('panel').addEventListener('contextmenu', (ev) => {
  event.preventDefault();
  const {x, y} = ev;
  //  弹出上下文菜单
  menu.popup({x, y});
  return false;
});

When you need to close the upper and lower menus under certain circumstances, you only need to call the colsePopup(browserWindow) method of the menu object. If the application involves multiple windows and you need to close the context menu of other windows, you can pass in this window as a parameter, and the default is to operate the current window.

The rest is exactly the same as the application menu.

Tray menu

The tray menu is the menu when you click in the lower right corner of the window, and on the mac is the menu when the small application icon is clicked on the upper right.

But the default application is not displayed in the tray To display the need to use Electron in Tray class to create.

Use the following demo code to create a tray icon and associate the clicked tray menu.

const {app, Menu, Tray, BrowserWindow} = require('electron')
let tray;
let contextMenu;

function createWindow() {
  win = new BrowserWindow({
    file: 'index.html'
  });
  win.loadFile('./index.html');
  //  创建 Tray 对象,并指定托盘图标
  tray = new Tray('/images/tray.png');
  //  创建用于托盘图标的上下文菜单
  contextMenu = Menu.buildFromTemplate([{
      label: '复制',
      role: 'copy'
    },
    {
      label: '剪切',
      role: 'cut'
    },
    {
      label: '粘贴',
      role: 'paste'
    }
  ]);
  //  设置托盘图标的提示文本
  tray.setToolTip('这是Electron的应用托盘图标')
  //  将托盘图标与上下文菜单关联
  tray.setContextMenu(contextMenu)
  win.on('closed', () => {
    tray.destroy();
    win = null;
  });
}

app.on('ready', createWindow)
app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});

The key operation instructions are as follows:

  1. Use new Tray(image) to create an application tray.
  2. Use setToolTip(toolTip) to add toolTip to the tray.
  3. Configure the menu, and use setContextMenu to associate the menu with the tray. is a must, and the tray icon must have a context menu to display

The demonstration effect is as follows:

Effects in windows:

93771-9tyb2dsfxts.png

On Mac:

46860-n7cfzl73yo.png

For more instructions on the system tray Tray and please refer to the official document System Tray

Different solutions for interaction in different systems:

In windows, directly click the application tray to activate the current application, and right-click to display the tray menu. In Mac, usually the left-click is to display the tray menu. If you need your application to have the same interaction method on each platform, you can manually adjust it with the code. The following events and methods are involved:

  • click when the tray is clicked
  • right-click tray is right-clicked
  • tray.popUpContextMenu([menu, position]) The context menu of the tray icon pops up. menu is passed in, the menu will pop up instead of the context menu of the tray icon. The parameter position only available on Windows and has the default value (0, 0)

Bubble notification in windows system tray

The application tray has a very useful and common function in the windows system-bubble notification, just use the displayBalloon() method of the tray. The demonstration is as follows:

tray.displayBalloon({
  // icon: './images/icon.png', // 通知的图标 (可选) 
  title: '气泡通知标题',
  content: '气泡通知的内容'
});
tray.on('balloon-show', () => {
  console.log('气泡通知显示');
});
//  添加气泡消息单击事件
tray.on('balloon-click', () => {
  console.log('气泡通知被用户点击');
});
//  添加气泡消息关闭事件
tray.on('balloon-closed', () => {
  console.log('气泡通自动关闭');
});

The bubble notification also has the function of clicking, so the system tray also has the following events:

  • balloon-show , triggered when the bubble message is displayed;
  • balloon-click , triggered when the bubble message is clicked;
  • balloon-closed , triggered when the bubble message is closed.

It should be noted that: balloon-click and balloon-closed are mutually exclusive, they will only trigger one of them: after clicking the bubble message, the bubble message will be closed immediately, in this case, balloon-closed will not be triggered Event; the balloon-closed event is only triggered when the bubble message is automatically closed after a few seconds.

The renderings are as follows:

40015-7qu5j9xe54i.png

16358-vk3qkgsjpe.png

The above is the description of the commonly used methods of Electron's native menu. For more in-depth content, please refer to the following:


依韵_宵音
1.1k 声望23 粉丝