如何通过Electron制作一个高度定制化的系统菜单栏?

发布时间:浏览:62

这里补充一下,我们选择Electron作为开发框架。对于我们来说,Electron可以使用前端语言(HTML+CSS+JS),可以是跨平台的框架,是最好的选择。

解题思路

1.正常人的想法是首先检查Electron是否有集成良好的API。我也不例外,于是我四处寻找,发现了一个系统托盘Tray模块。大概的API模板如下:

const { app, Menu, Tray }=require(' Electron')let tab=null;let openVoice=true;app.whenReady().then(()={ 托盘=new Tray('/path/to/my/icon'); const contextMenu=Menu.buildFromTemplate([ { label: openVoice ? '关闭声音' : '打开声音', icon: openVoice ? 'trayMenu/notVoice.png': 'trayMenu/voice.png', click: (event: any)={ openVoice=!openVoice; }, }, { label: '退出', icon: 'trayMenu/exit.png', click: ()={ app.exit(0) } } ]); ('这是我的应用程序。')托盘.setContextMenu(contextMenu)}) 实际效果大概是这样的:

总体来说,它支持了标题、图标、子菜单、点击回调等常见的东西,似乎和我们理想想要的差距很大。不信的话我就想是否可以支持渲染HTML,所以我在contextMenu中额外添加了一个子项:

{ label: '测试

', icon: 'trayMenu/exit.png', click: ()={ app.exit(0); }} 结果也相当感人。输出与我写的完全一样。看来这个办法是不行的。

2. 自己定制一个系统菜单栏。根据我们之前的观点,我们基本上可以看出,系统托盘Tray除了创建托盘图标之外,对我们来说基本上没有任何用处。于是,我们想到了使用浏览器窗口(BrowserWindow)作为菜单栏。这样,菜单栏应该是什么样子就完全掌握在我们手中了,但是我们首先要解决以下问题:

(1)如何监听鼠标在我们的托盘图标上的滑动。我们首先创建相应的菜单栏窗口,默认情况下是隐藏的。

menuWin=new BrowserWindow({ modal: true,autoHideMenuBar: true,disableAutoHideCursor: true,frame: false,show: false,});menuWin.loadURL(config.frontUrl + '/#/newMessage'); //加载对应的菜单栏页面。查看了托盘API后,只找到了一个鼠标移动事件来处理这个问题,但是这个事件只有在托盘滑入托盘时才会触发,并没有对应的抽出托盘的事件,所以我们还是需要制定一个机制。判断鼠标是否滑出托盘,具体参见下面的代码。

从' Electron' 导入{ app、Tray、Menu、nativeImage、screen、BrowserWindow、BrowserView、shell };let isLeave=true; //存储鼠标是否离开托盘的状态托盘.on('mouse-move', (event: any ,point: any)={ if( isLeave==true ) { //当菜单移入菜单时for第一次从其他地方开始显示菜单页面,然后在菜单内移动时不再重复显示菜单menuWin.show(); } isLeave=false; checkTrayLeave();});/** *检查鼠标是否离开托盘*/checkTrayLeave() {clearInterval(this.leaveInter) this.leaveInter=setInterval(()={ let tabBounds=tab.getBounds() ; let point=screen.getCursorScreenPoint(); //判断是否在托盘中if(!(trayBounds.x point.x为何trayBounds.y point.y point.x(trayBounds.x+trayBounds.width)point.y(trayBounds.y+trayBounds.height))){//触发鼠标离开clearInterval(this.leaveInter); //隐藏菜单栏isLeave=true; } else { console.log('isOn');控制窗口的位置

根据上一步的代码,我们可以看到,可以使用tray.getBounds()来获取托盘图标的位置信息。我们首先假设菜单栏的高度和宽度都是200:

让托盘Bounds=this.appTray.getBounds(); if(!params.x){ params.x=托盘Bounds.x -(200/2)}if(!params.y){ params.y=托盘Bounds.y - params .height;} this.menuWin.setBounds(params);做这一步的时候,基本上就是当鼠标滑入滑出我们的托盘图标时,它控制了菜单栏的显示和隐藏。但我们会发现一个问题。当我们将鼠标滑动到菜单栏窗口时,菜单栏就会被隐藏,这样我们就根本不能做任何事情了。因此,第一步识别托盘位置时,我们需要将整个菜单栏窗口纳入我们系统托盘滑动的正常范围内:

/** * 检查鼠标是否离开托盘*/checkTrayLeave() {clearInterval(this.leaveInter) this.leaveInter=setInterval(()={ let patrayBounds=trap.getBounds(); let point=screen.getCursorScreenPoint() ; //判断是否在托盘中if(!(trayBounds.x point.x托盘Bounds.y point.y point.x (trayBounds.x +托盘Bounds.width) point.y (trayBounds.y +托盘Bounds.height) )){ //判断是否在弹出菜单中let menuBounds=this.menuWin.getBounds() if(menuBounds.x point.x menuBounds.y point.y point.x (menuBounds.x + menuBounds.width ) point.y (menuBounds.y + menuBounds.height)) { console.log('isOnMenupage'); return ; } //触发鼠标离开clearInterval(this.leaveInter); //隐藏menu bar isLeave=true; } else { console.log('isOn');

总结

基本上,自定义系统菜单栏的整个解决方案大概就是这样一个过程,但是这个解决方案是有限的对window和mac系统,与Linux确实无法做到兼容,大部分API都不支持Linux系统。

用户评论

あ浅浅の嘚僾

我一直想了解Electron能做到多定制的操作啊!这个教程很详细,看后终于明白怎么修改菜单栏了。

    有13位网友表示赞同!

♂你那刺眼的温柔

看了下代码示例,感觉难度不大!我已经开始尝试在自己的项目里使用 electron 自定义菜单栏了,期待效果。我最近还在研究如何让它更像是原生应用的感觉,你还有其他的建议吗?

    有8位网友表示赞同!

寂莫

讲道理这个标题看着就让人误解,Electron 菜单和系统菜单栏是两个概念吧?还是说可以将自定义的 Electron 菜单栏替换掉系统自带的呢?我很想弄清楚。

    有12位网友表示赞同!

安陌醉生

终于找到学习 electron 自定义菜单栏的教程了!之前总是找不到合适的资料。希望这篇教程能帮到更多人。

    有19位网友表示赞同!

西瓜贩子

Electron的菜单栏可定制性确实很高,但这篇文章写的有点过于基础,对于入门较早的人来说可能不太有实用价值。希望能提供一些更高级的使用技巧和案例分析。

    有10位网友表示赞同!

凉城°

这篇文章说的挺清楚的,我按照步骤操作后顺利自定义了菜单栏,效果简直不要太好!终于告别那标准的一条线!

    有12位网友表示赞同!

我要变勇敢℅℅

Electron 的系统菜单栏确实非常棒,可以完美融合系统风格,但如果要高度自定义的话确实需要花点时间学习。这篇文章还是有些难读,希望可以在语言上更简洁易懂一些。

    有14位网友表示赞同!

┲﹊怅惘。

我之前尝试过 Electron 自带的菜单栏设置,感觉比较僵硬,无法满足我的需求,现在看到这个教程感觉很有潜力!我要试试看能不能用它做一套完整的自定义菜单栏了。

    有9位网友表示赞同!

红尘滚滚

Electron 的菜单栏功能确实强大,可以打造出丰富的菜单结构和个性化的操作体验。但是学习成本相对较高,需要比较深入的了解 Electron 框架。

    有5位网友表示赞同!

矜暮

这篇文章写的太详细了,我只需要知道怎么实现自定义菜单栏,至于那些复杂的代码细节并不重要。希望以后能提供一些更精简的教程。

    有9位网友表示赞同!

挽手余生ら

这个电子菜单栏的功能很棒,而且自定义程度很强! 感觉可以做很多有趣的应用!我要试试看能不能用它做一个桌面工具助手!

    有20位网友表示赞同!

浮世繁华

虽然文章介绍了 Electron 自定义菜单栏的方法,但是对于初学者来说,还是有些难度。希望能有更多的图文讲解和实例代码,以便更容易上手。

    有14位网友表示赞同!

゛指尖的阳光丶

学习Electron自定义菜单栏一直是我的愿望,这个教程终于满足我的需求了! 看后终于明白怎么修改菜单栏了。

    有5位网友表示赞同!

命硬

我一直在寻找一个能用 Electron 实现高度自定义功能的教程。这篇教程非常详细,涵盖了从基础知识到高级定制技巧,真是一份学习宝藏!

    有14位网友表示赞同!

空谷幽兰

Electron 的系统菜单栏确实很棒,可以完美融合系统风格。 这次教程分享的自定义方法也很实用!我试着将它应用在我的项目中,期待能打造出更符合用户需求的操作界面。

    有19位网友表示赞同!

热点资讯