天天看点

electron实现子窗口中创建右键菜单

作者:中二少年学编程

后续可能会用electron开发一些工具,包括不限于快速生成个人小程序、开发辅助学习的交互式软件、帮助运维同学一键部署的简易版CICD工具等等。

开发进度,取决于我懒惰的程度。

不过不嫌弃的同学还是可以先关注一波小程序——中二少年工具箱,真的发布工具了,肯定还是需要一个统一下载入口的,各个博客平台有点不太合适。

前言

有位同学问到一个问题,大致意思就是他创建了子窗口,但是子窗口的右键菜单没有生效,如图:

electron实现子窗口中创建右键菜单

他的代码大致看了下,虽然没找到

webContents.on('context-menu', (e, params) => {
          contextMenu.popup()
        })           

但是代码里有contextMenu.popup(),应该是在某个地方做了监听吧。

因为没有完整代码,我没办法明确告诉同学具体哪里做错了,但我可以把正确写法发布出来,免得一直在评论区长篇对话。

一、右键菜单创建

右键菜单的创建大致分为这么几步:

  1. 创建一个窗口,这是放右键菜单的容器:
let win=new BrowserWindow(options)           

BrowserWindow是electron提供的对象,可自行查阅。

  1. 创建右键菜单:
//    创建右键菜单
        let contextMenu = Menu.buildFromTemplate([
            {label: 'Item 1' || test,role:'reload'},
            {role: 'editMenu'}
        ])           

Menu同样是electron提供的对象。

  1. 把第二步创建的菜单放到第一步创建的窗口:
win.webContents.on('context-menu', (e, params) => {
          contextMenu.popup()
        })           

webContents是BrowserWindow的一个属性,实例化后可以调用。

二、为子窗口创建右键菜单

通过上面章节,大家了解了如何创建右键菜单,我们会发现一个规律,那就是我们为某个窗口挂载了对应的右键菜单,这是对应关系。

那么如果创建子窗口,如何为子窗口创建右键菜单呢?

其实很简单,就是重复一遍上面的操作。

我自己demo里面封装解耦有点多,如果不通读项目,可能会增加理解成本,所以这里就参考主窗口菜单实现,复制粘贴实现子窗口菜单了,这种屎山代码前身,希望不要影响看到的同学。

对应上面章节的步骤:

  1. 创建一个主窗口,然后再创建一个子窗口:
let win=new BrowserWindow(options)
    let child = new BrowserWindow({ parent: this.win , modal: true,})
    child.loadURL('https://baidu.com')           

2. 创建主窗口右键菜单,我又复制实现子窗口右键菜单:

//    创建主窗口右键菜单
        let contextMenu = Menu.buildFromTemplate([
            {label: 'Item 1' || test,role:'reload'},
            {role: 'editMenu'}
        ])
//    创建子窗口右键菜单
        let contextMenuTest = Menu.buildFromTemplate([
            {label: 'Item 2' || test,role:'reload'},
            {role: 'editMenu'}
        ])           

3. 把第二步创建的菜单放到第一步创建的窗口:

win.webContents.on('context-menu', (e, params) => {
          contextMenu.popup()
        })
child.webContents.on('context-menu', (e, params) => {
          contextMenuTest.popup()
        })           

注意:不要直接抄代码,重点看思路。因为这就是屎山代码,我在自己demo里试验通过后,会对某些封装过的方法复制粘贴,会修改变量名,万一哪多个空格,少个变量,别骂我。

最终效果:

electron实现子窗口中创建右键菜单
electron实现子窗口中创建右键菜单

2.一点小问题

因为这个窗口是主窗口的子窗口,所以这里直接写主窗口的show方法就可以,子窗口会自动显示。

//等待dom渲染后打开窗口
        this.win.on('ready-to-show', () => {
            this.win.show()
        })           

如果哪天你的需求变得很复杂,可能会有各种层级,需要在很多地方控制不同窗口的show,那么记得做好窗口是否存在的判断,例如:

this.win.on('ready-to-show', () => {
            this.win.show()
            console.log('ccccccccccccccc',child)
            if(!child.isDestroyed()){
                child.show()
            }
        })           

child关闭后,对象不是null,所以必须通过它的isDestroyed方法判断。

总结

大家有什么问题也可以私信博主,没人问都懒得写文章了。

继续阅读