Electron 编写菜单栏
在很多桌面应用程序的顶部都有一个菜单栏,把一些功能入口放到菜单栏的菜单中可以使软件界面更简洁。Electron 可以支持原生菜单栏,也可以用 HTML 来制作菜单栏,不过原生菜单栏在键盘操作和可访问性方面都要更好。
禁用菜单
Electron 默认会显示一个菜单栏,其中包含了退出、刷新、打开控制台 等功能,如果不需要菜单栏的话可以禁用,如下:
const {Menu} = require('electron'); // 引入 Menu 模块
Menu.setApplicationMenu(null);
菜单栏需要在 main
主进程中配置。
制作菜单模板
为了方便管理可以单独创建一个菜单模板文件来编写菜单栏,下面是一个简单的菜单栏:
const {Menu} = require('electron'); // 引入 Menu 模块
// 菜单栏模板
const menuBar = [
{
label: '文件',
submenu: [
{label: '打开'},
{label: '保存'},
{label: '退出'}
]
},
{
label: '帮助',
submenu: [
{label: '访问官网'},
{label: '关于'}
]
}
];
// 构建菜单项
const menu = Menu.buildFromTemplate(menuBar);
// 设置一个顶部菜单栏
Menu.setApplicationMenu(menu);
菜单模板使用对象和数组,其中 label
是菜单项名称,submenu
是子菜单。
在 main
主进程的 ready
事件中使用 require
引入菜单模板文件就可以看到菜单栏了。
上面只是编写了菜单模板,下面就给菜单添加点击事件:
const {Menu, app} = require('electron');
// 菜单栏模板
const menuBar = [
{
label: '文件',
submenu: [
{label: '打开'},
{label: '保存'},
{
label: '退出',
click() {
// 退出程序
app.quit();
}
}
]
}
];
// 构建菜单项
const menu = Menu.buildFromTemplate(menuBar);
// 设置一个顶部菜单栏
Menu.setApplicationMenu(menu);
可以直接在菜单项中写 click
函数。
Electron 的菜单配置是写在 main
主进程中的,如果需要通过菜单控制渲染进程可以使用 BrowserWindow
的 webContents.send
给渲染进程发送指令。
绑定快捷键
在很多文件和编辑菜单的名称后面应该都可以看到 ctrl + o
或 ctrl + s
的快捷键提示,Electron 也可以给菜单绑定快捷键,只需要按快捷键就可以触发菜单的点击事件。
菜单项可以使用 accelerator
属性来设置快捷键,如下:
// 菜单栏模板
const menuBar = [
{
label: '文件',
submenu: [
{
label: '打开',
accelerator: 'ctrl+o'
},
{
label: '保存',
accelerator: 'ctrl+s'
},
{
label: '退出',
accelerator: 'ctrl+w',
click() {
// 退出程序
app.quit();
}
}
]
}
];
打开菜单也可以看到快捷键提示,如下:
单选和多选菜单
一些快捷设置的菜单可能会需要用到 checkbox
多选和 radio
单选,例如下面的 Windows 记事本的格式菜单就用到了单选功能:
Electron 的菜单也支持多选和单选,把菜单项的 type
属性设置为 checkbox
就是多选,如下:
// 菜单栏模板
const menuBar = [
{
label: '查看',
submenu: [
{
label: '显示工具栏',
type: 'checkbox',
checked: true,
click(ev) {
// 输出选中状态
console.log(ev.checked ? '已选中' : '未选中');
}
},
{
label: '显示状态栏',
type: 'checkbox',
checked: false,
click(ev) {
// 输出选中状态
console.log(ev.checked ? '已选中' : '未选中');
}
}
]
}
];
checked
属性可以设置菜单的选中状态,点击菜单时 checked
的状态会改变,click
函数可以接收一个 event
,通过 event
对象可获取菜单项的各种属性,包括 checked
选中状态。
Electron 的多选菜单如下:
把菜单项的 type
设置为 radio
就是单选,如下:
// 菜单栏模板
const menuBar = [
{
label: '主题配色风格',
submenu: [
{
label: '亮色',
type: 'radio',
checked: true,
click(ev) {
if (ev.checked) console.log('Light');
}
},
{
label: '暗色',
type: 'radio',
click(ev) {
if (ev.checked) console.log('Dark');
}
},
{
label: '高对比度',
type: 'radio',
click(ev) {
if (ev.checked) console.log('High contrast');
}
}
]
}
];
一组菜单只有一项可以选中,点击其中的一项其他项都会取消选中,单选菜单也是通过 checked
来设置选中状态,通过 event
的 checked
也能获取选中状态。
单选菜单的效果如下:
分隔线
一组相似功能的菜单项之间可以用分隔线分隔,把菜单项的 type
属性设置为 separator
就可以显示分隔线了,如下:
// 菜单栏模板
const menuBar = [
{
label: '文件',
submenu: [
{label: '打开'},
{label: '保存'},
{type: 'separator'},
{label: '退出'}
]
}
];
效果如下:
快捷键展开菜单
很多菜单栏的菜单展开按钮的名称后面都可以看到一个字母提示,如下:
直接按 Alt + F
就能展开文件菜单、按 Alt + E
就能展开编辑菜单。
Electron 也可以通过快捷键展开菜单,只需要在顶层的 label
属性的字母前加 &
就能通过 Alt + label 首字母
展开菜单。
如下:
// 菜单栏模板
const menuBar = [
{
label: '&File',
submenu: [
{label: 'Open'},
{label: '保存'},
{label: '退出'}
]
},
{
label: '&Edit',
submenu: [
{label: '复制'},
{label: '粘贴'}
]
}
];
通过 Alt + F
就能展开 File
菜单、通过 Alt + E
就能展开 Edit
菜单,字母前的 &
是不会显示的,如果需要提示的话可以在后面加 (F)
。
通过这种方法只能展开英文的菜单,中文的方法目前还没有找到合适的,即便在中文前面加 &F
其中的 F
也会显示出来。
动态增加菜单项
有时候可能会需要动态增加菜单项,例如有的文件菜单会有一个子菜单叫 最近打开的文件
,其中的内容就是动态增加的,不是固定的。
动态增加菜单还需要引入 MenuItem
模块,下面创建一个菜单,然后给 最近打开的文件
动态插入子菜单:
const {Menu, MenuItem} = require('electron');
// 菜单栏模板
const menuBar = [
{
label: '文件',
submenu: [
{label: '打开'},
{label: '保存'},
{
label: '最近打开的文件',
id: 'fileList',
submenu: []
},
{label: '退出'}
]
}
];
// 构建菜单项
const menu = Menu.buildFromTemplate(menuBar);
// 设置一个顶部菜单栏
Menu.setApplicationMenu(menu);
// 动态创建的菜单模板
const fileItem = new MenuItem({
label: 'file1.txt'
});
// 获取 id 为 fileList 的菜单,然后把菜单添加到子菜单中
menu.getMenuItemById('fileList').submenu.append(fileItem);
// 重新设置顶部菜单栏
Menu.setApplicationMenu(menu);
下面是代码说明:
- 使用菜单模板创建了一个菜单,其中
最近打开的文件
的子菜单为空,并且设置了一个 id。 - 使用
new MenuItem
创建了一个菜单项。 - 通过
getMenuItemById
ID 选择器获取了之前创建的最近打开的文件
,然后给submenu
子菜单插入了一个菜单项。 - 使用
Menu.setApplicationMenu
重新设置顶部菜单栏。
动态增加的菜单如下:
role 属性
在 HTML 中 role
属性可以给屏幕阅读器之类的辅助软件提供可访问性方面的支持,在 Electron 菜单中 role
属性包含了一些预定义功能,有些功能使用 role
就可以实现,无需在 click
中手动编写。
下面是一组包含 role
属性的菜单:
// 菜单栏模板
const menuBar = [
{
label: '预定义功能',
submenu: [
{
label: '打开开发者工具',
role: 'toggledevtools'
},
{
label: '全屏',
role: 'togglefullscreen'
},
{
label: '重新加载',
role: 'reload'
},
{
label: '退出',
role: 'quit'
}
]
}
];
上面的功能都无需编写 click
,添加 role
属性就能直接实现。
完整的 role
属性说明可以访问:https://www.electronjs.org/docs/api/menu-item 。
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/896/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。
学习学习,必须的!谢谢!