在熟悉了主进程窗口的创建和其他常用 api 后,本讲我们来看一下如何给窗口设置菜单栏以及如何添加对话框和快捷键等常见的桌面应用特性。
菜单、快捷键和对话框的定制基本也都是基于窗口实例的,Electron 提供了对应的配置项和 api 来快速实现。
菜单及快捷键
菜单是桌面软件非常熟悉的功能区,如下图。
Electron 配置项
Electron 为我们提供了 Menu 模块用于设置菜单项,并且对于常用的功能,Electron 已经帮我们实现了,我们要做的只是设置一下选项和文案。
// main.js 主进程
const { Menu } = require('electron')
// 菜单配置项
const menuTemplate = [ { label: '文件', submenu: []
},
{
label: '编辑',
submenu: [
{ label: '复制', role: 'copy'},
]
}
]
Menu.setApplicationMenu(menu); // 应用菜
上面代码定制了两个菜单“文件”和“编辑”,并且为编辑添加了个子选项“复制”。这里并不需要我们去实现复制的具体功能。而是通过 role 字段指定 Electron 提供的复制能力。这样,就完成了整个功能的设置。
常见 role 字段值:
- copy:复制
- cut:剪切
- paste:粘贴
- togglefullscreen:全屏
- undo:撤销
- redo:回退
- about:关于
- help:帮助
- minimize:最小化
- selectAll:全选
- ......
自定义功能
Electron 提供了最常用的功能减少我们开发,我们也可以自定义功能按钮和处理逻辑,取消 role 字段的指定,并且绑定点击事件即可,如下代码。
// main.js
const { Menu } = require('electron')
// 菜单配置项
const menuTemplate = [ { label: '文件', submenu: []
},
{
label: '编辑',
submenu: [
{ label: '复制', role: 'copy'},
{
label: '自定义名称', // 自定义按钮的名称
click: () => {
// 自定义处理逻辑
}
},
]
}
]
Menu.setApplicationMenu(menu); // 应用菜
快捷键
上面设置的菜单,一般都会同时设置快捷键,这个也很方便。只需要设置字段 accelerator 即可。如下,我们为复制功能添加了快捷键 Cmd+C(mac 系统)或 Ctrl+C(windows 系统)。这里很方便的一点是在 Electron 中直接写 CmdOrCtrl 就同时兼容了 Windows 和 Mac 系统,而不用开发者去做额外的判断逻辑。
// main.js 主进程
const { Menu } = require('electron')
// 菜单配置项
const menuTemplate = [
{
label: '编辑',
submenu: [
{ label: '复制', role: 'copy', accelerator: 'CmdOrCtrl+C'},
]
}
]
Menu.setApplicationMenu(menu);
常见的快捷键还有 CmdOrCtrl+N(新建)、CmdOrCtrl+O(打开)和 CmdOrCtrl+S(保存)等等。
通过 Api 设置菜单
通过 MenuItem 模块也可以为菜单添加子菜单,相对于前面的配置方式,MenuItem 可以更加灵活的在设置菜单时增加其他处理逻辑。
// main.js 主进程
const { Menu, MenuItem } = require('electron')
const menuTemplate = [
{label: '文件'},
{label: '编辑'},
{label: '视图'},
{label: '关于'}
]
const menuItem = new MenuItem({label: '新建'})
menu.items[0].submenu.append(menuItem); // 给第一个主菜单加入子菜单"新建"
对话框
在网页系统中,一般对话框是由 html 来实现的,或者通过 input[type=file] 来触发的文件选择。接下来主要介绍在 Electron 中调用桌面原生对话框的能力,如文件选择、目录选择等。和 web 的文件选择器不同,因为 Electron 构建的是桌面应用,所以对于文件的操作权限是很高的,可以获取文件所有常用信息,比如路径、大小等,也可以删除创建文件,这里是没有 web 环境下时浏览器的限制的。
Electron 中的对话框主要是通过 dialog 模块来完成的。dialog 模块提供了非常实用的对话框能力,如选择文件或目录、可单选或多选、可同步或异步调用,还有消息框和错误框等等。
文件选择框
如下图,弹出原生文件夹选择框,供用户选择文件或者目录,然后将用户选择的结果(包括取消操作)返回给应用程序。
// main.js 主进程
const { app, dialog } = require('electron')
function init() {
dialog.showOpenDialog() // 打开文件选择器
}
app.whenReady().then(init) // app read 后初始化创建窗口
当然 dialog.showOpenDialog 返回一个 Promise 对象,可以在返回中获取用户选择结果。可以有丰富的参数控制具体行为,如可以限制用户只能选择文件,不能选择目录,或者打开时默认进入到某个目录、是否可多选等等
// main.js 主进程
const { app, dialog } = require('electron')
function init() {
// 打开文件选择器
dialog.showOpenDialog({
title: '自定义弹窗标题',
defaultPath: app.getPath('desktop'), // 默认打开桌面所在目录
properties: {
openFile: true, // 可以选择文件
openDirectory: false, // 不允许选择文件夹
multiSelections: true, // 允许多选
}
}).then((result) => {
console.log(result.canceled) // 用户是否取消了选择
console.log(result.filePaths) // 用户选择的路径数组
})
}
app.whenReady().then(init) // app read 后初始化创建窗口
文件保存框
文件保存框一般用于将用户的文件保存到某个自定义目录,由用户选择需要保存的目录和名称,当然也可以设置默认路径和名称,通过 dialog.showSaveDialog 实现。
// main.js 主进程
const { app, dialog } = require('electron')
function init() {
// 保存文件弹窗
dialog.showSaveDialog({
title: '自定义标题',
defaultPath: app.getPath('desktop'), // 默认保存在桌面
}).then((result) => {
console.log(result.canceled) // 用户是否取消了选择
console.log(result.filePath) // 用户选择的单个路径(字符串)
})
}
app.whenReady().then(init) // app read 后初始化创建窗口
消息提示框
原生消息提示框个通过 dialog.showMessageBox 实现,可以通过 message 控制提示内容,type 控制消息类型("none", "info", "error", "question" 或者 "warning" ),其图标不一样。
// main.js 主进程
const { app, dialog } = require('electron')
function init() {
// 打开 MessageBox
dialog.showMessageBox({
message: '这是 MessageBox 弹窗',
type: 'error'
})
}
app.whenReady().then(init) // app read 后初始化创建窗口
另外错误弹窗也可以用 dialog.showErrorBox 来实现,如下图,此 api 可以在 ready 之前调用,它通常在启动时报告错误。
// main.js 主进程
const { app, dialog } = require('electron')
function init() {
dialog.showErrorBox('错误框标题','错误框内容')
}
app.whenReady().then(init) // app read 后初始化创建窗口
总结
本文介绍了 Electron 提供的特别方便的原生能力,包括初始化配置项和文件选择器等,建议动手去做一遍,修改不同的参数看看具体的效果,这样有助于加深运用熟练度。