电子使用加速器调用上下文菜单中的菜单项

Electron using Accelerator to call a menu item in context menu

本文关键字:菜单 菜单项 上下文 调用 加速器      更新时间:2023-09-26

如何在上下文菜单中使用accelerator调用menu item ?

var menu = new Menu();
menu.append(new MenuItem({
  label: 'Say something',
  click: function(){
    alert("Hello");
  },
  accelerator: "CmdOrCtrl+E"
}));

window.addEventListener('contextmenu', function (e) {
  e.preventDefault();
  menu.popup(currentWindow);
}, false);

上面的代码可以工作。上下文菜单出现,当单击菜单项时,单击回调工作。

但是加速器命令不起作用。什么好主意吗?


方面的问题:

可以将click event传递给menu.popup,然后再传递给menu-item click callback吗?现在我只是将click事件存储在一个全局变量中

我不相信Electron会注册加速器,除非你调用Menu.setApplicationMenu(menu)或等效的。在你的代码片段中,你创建了一个菜单,但你并没有真正做任何事情,直到你调用popup方法。在你注册加速器之前,艾柯顿怎么知道你想用它?当它们被设置到应用程序菜单中时,这些是注册的。

话虽这么说,它看起来不像电子提供了一种简单的方法来注册一个本地的,只有渲染进程的快捷方式,而不创建一个BrowserWindow菜单。在OSX中,加速器是由操作系统的菜单系统处理的,而不是由Electron来处理的,因此为这些没有菜单的本地化快捷方式添加跨平台支持将需要对OSX版本进行大量的工作。

建议的解决方案是在JavaScript中捕获您想要的快捷方式,然后以这种方式触发命令。您仍然可以使用加速键选项来表示上下文菜单中的键组合。

我发现今天注册上下文菜单加速器最简单的方法是将上下文菜单附加到应用程序菜单中,这将注册它们,但设置visible: false使它们实际上不会出现。

使用菜单模板非常简单。

function registerAppMenu(app, invisibleMenus) {
  const template = [ ... ]; // use app to create the file-menu
  template.push(...invisibleMenus.map(menu => ({...menu, visible: false})));
  Menu.setApplicationMenu(Menu.buildFromTemplate(template));
}

最好是这样:

const {Menu} = require('electron').Menu;
const mainMenu = Menu.buildFromTemplate(mainMenuTemplate);
Menu.setApplicationMenu(mainMenu)

所以你可以使用

mainMenuTemplate.push({
    /* your menu item properties*/
});`

将其推到最后。使用unshift()而不是push()来添加到mainMenuTemplate的开始,但是即使是添加了加速器也可以正常工作。