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

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

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

不过不嫌弃的同学还是可以先关注一波小程序,真的发布工具了,肯定还是需要一个统一下载入口的,各个博客平台有点不太合适。
在这里插入图片描述


前言

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

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

  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')
  1. 创建主窗口右键菜单,我又复制实现子窗口右键菜单:
//    创建主窗口右键菜单
        let contextMenu = Menu.buildFromTemplate([
            {label: 'Item 1' || test,role:'reload'},
            {role: 'editMenu'}
        ])
//    创建子窗口右键菜单
        let contextMenuTest = Menu.buildFromTemplate([
            {label: 'Item 2' || test,role:'reload'},
            {role: 'editMenu'}
        ])
  1. 把第二步创建的菜单放到第一步创建的窗口:
 win.webContents.on('context-menu', (e, params) => {
          contextMenu.popup()
        })
child.webContents.on('context-menu', (e, params) => {
          contextMenuTest.popup()
        })

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

最终效果:
在这里插入图片描述

在这里插入图片描述

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方法判断。


总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中二少年学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值