应用菜单

要创建自定义菜单,你需要使用 ElectronMenu 模块。下面是个例子:

const { app, BrowserWindow, Menu } = require('electron')

// 创建菜单模板
const myMenus = [
    {
        label: '文件',
        submenu: [
            {
                label: '打开',
                accelerator: 'CmdOrCtrl+O', // 快捷键
                click() {
                    // 处理打开操作
                }
            },
            {
                label: '保存',
                accelerator: 'CmdOrCtrl+S',
                click() {
                    // 处理保存操作
                }
            },
            {
                type: 'separator' // 添加分隔线
            },
            {
                label: '退出',
                accelerator: 'CmdOrCtrl+Q',
                click() {
                    app.quit(); // 退出应用程序
                }
            }
        ]
    },
    {
        label: '编辑',
        submenu: [
            { role: 'undo' },
            { role: 'redo' },
            { type: 'separator' },
            { role: 'cut' },
            { role: 'copy' },
            { role: 'paste' },
            { role: 'pasteAndMatchStyle' },
            { role: 'delete' },
            { role: 'selectAll' }
        ]
    }
];

// 创建菜单
const menu = Menu.buildFromTemplate(myMenus);
// 将菜单设置为应用程序的菜单
Menu.setApplicationMenu(menu)

app.on('ready', () => {
    const win = new BrowserWindow({ width: 800, height: 600 })
})

当涉及 Electron 的 Menu 模块时,以下是一些主要的知识点:

  1. 创建菜单:使用 Menu.buildFromTemplate(template) 方法可以根据提供的菜单模板创建菜单对象。菜单模板是一个包含菜单项的数组,每个菜单项都有自己的属性,如标签(label)、快捷键(accelerator)、角色(role)和点击事件(click)等。
  2. 设置应用程序菜单:使用 Menu.setApplicationMenu(menu) 方法可以将菜单设置为应用程序的菜单。通过调用这个方法,你可以在应用程序的菜单栏或窗口中显示自定义的菜单。
  3. 菜单项属性:

    • label:菜单项显示的文本。
    • accelerator:为菜单项指定快捷键,允许用户使用键盘快速访问菜单项。
    • click:菜单项被点击时触发的回调函数。
    • role:使用内置的角色来指定一些常见操作的行为,如复制('copy')、剪切('cut')、粘贴('paste')等。这些角色会根据操作系统的约定自动处理相应的操作。
    • submenu:指定一个子菜单,允许创建层级嵌套的菜单。
  4. 分隔线和标签:通过在菜单模板中使用 type: 'separator' 可以添加分隔线,用于在菜单中分隔不同的菜单项。你还可以使用 type: 'label' 来创建一个标签,它是一个不可点击的文本项,用于在菜单中提供额外的说明或分组。
  5. 上下文菜单:除了应用程序菜单,你还可以创建上下文菜单(也称为右键菜单)。通过监听特定的事件(如 contextmenu),可以在合适的时候显示自定义的上下文菜单。
菜单项和role相关的信息可以参考:https://www.electronjs.org/zh/docs/latest/api/menu-item

右键菜单

自定义右键菜单和自定义应用菜单用法基本差不多,也是通过Menu 模块实现的。由于右键菜单的显示一般发生在渲染进程中,所有我们需要使用进程间通信和预处理脚本。下面是一个例子:

// 主进程 main.js
const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('path')
// 1.创建菜单模板
const myMenus = [
    {
        label: '菜单1',
        accelerator: 'CmdOrCtrl+O', // 快捷键
        click() {
            // 处理打开操作
        }
    },
    {
        label: '菜单2',
        submenu: [
            { role: 'undo' },
            { role: 'redo' },
            { type: 'separator' },
            { role: 'cut' },
            { role: 'copy' },
            { role: 'paste' },
            { role: 'delete' },
            { role: 'selectAll' }
        ]
    }
];

// 2.创建菜单
const menu = Menu.buildFromTemplate(myMenus);

app.on('ready', () => {
    // 创建窗口
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'p1.js')
        }
    })
    win.loadFile('index.html')
    
    // 监听子进程的showContextMenu频道
    ipcMain.on('showContextMenu', function () {
        // 3.在窗口中显示右键菜单
        menu.popup()
    })
})
// 预处理脚本文件 p1.js
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('elecAPI', {
    showContextMenu: function () {
        // 向主进程showContextMenu频道发送信息
        ipcRenderer.send('showContextMenu')
    }
})
<!-- 渲染进程中的代码 -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>您好,世界</title>
</head>

<body>
    <h1>您好,世界!</h1>
    <script>
        document.addEventListener('contextmenu', function () {
            // 调用在预处理脚本中定义的函数,想法主进程发送信息
            elecAPI.showContextMenu()
        })
    </script>
</body>

</html>

参考文档:https://www.electronjs.org/zh/docs/latest/api/menu

Last modification:March 26, 2024
如果觉得我的文章对你有用,请随意赞赏