我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

感谢各位读者的支持,苏南大叔在本篇文章中,讲述的是electron程序,如何实现托盘图标及托盘的右键菜单。右键菜单是苏南大叔的说法,官方的说法是上下文菜单。

苏南大叔:electron程序,如何实现tray托盘图标及上下文菜单? - electron-tray
electron程序,如何实现tray托盘图标及上下文菜单?(图4-1)

本文测试环境:win10/electron@4.0.1。同时也解决几个常见的托盘图标相关的问题,比如:

  • error proccessing argument at index 0
  • 托盘图标过几分钟就自动消失

基本代码

主进程:

// const {app, Menu, Tray} = require('electron')
const { Menu, Tray } = require('electron')
const path = require('path');
let tray = null
app.on('ready', () => {
  //tray = new Tray("./favicon.png")
  tray = new Tray(path.join(__dirname,"./favicon.png"));
  const contextMenu = Menu.buildFromTemplate([
    { label: '退出', click:function(){app.quit()} }
  ])
  tray.setToolTip('测试气泡提示文字')
  tray.setContextMenu(contextMenu)
})
  • tray.setToolTip,这个是用于设置托盘的气泡提示文字的。
  • tray.setContextMenu,这个是用于设置托盘的上下文菜单的。
  • path.join(__dirname,"./favicon.png"),这个路径,请确保打包后还存在。

苏南大叔:electron程序,如何实现tray托盘图标及上下文菜单? - electron-tray-code
electron程序,如何实现tray托盘图标及上下文菜单?(图4-2)

在上述代码中,苏南大叔构建了一个托盘图标并设置了一个右键菜单。菜单项目是“退出”功能,点击后,程序体退出执行。效果图如下所示:

苏南大叔:electron程序,如何实现tray托盘图标及上下文菜单? - electron-tray-ui
electron程序,如何实现tray托盘图标及上下文菜单?(图4-3)

常见问题

electron实现托盘功能的过程中,经常有人问如下几个问题,非常典型。这里做个总结回复:

图标格式

可以用.png,也可以用.jpeg,还可以用.ico。推荐使用.png,并不是必须是套娃图标。如果您觉得图标太锯齿,不够清晰之类的,请美工重新设置个小图标试试,16*16或者32*32。当然,electron的托盘图标也支持根据屏幕的分辨率自动选择图标。但是并不是本文的讨论范畴,请期待苏南大叔的后续文章。

Error processing argument at index 0

报错信息如下:

Error processing argument at index 0, conversion failure from ./xxx.png

苏南大叔:electron程序,如何实现tray托盘图标及上下文菜单? - tray-error-index-0
electron程序,如何实现tray托盘图标及上下文菜单?(图4-4)

这个问题是非常的常见,太多人问起这个问题。答案就是:没找到图标文件,没找到图标文件,没找到图标文件。不用讲任何的“可是”“但是”“然而”,就是没有找到图标文件。

至于怎么才能找到图标文件,看你自己的代码逻辑:

  • 路径,确认使用了正确的路径了么?比如path.join
  • 文件打包进去了么?正常情况下来说,肯定是能打包进去的。不过也有新人生生的把这个图标排除在打包文件之外。
  • asar是否为true不重要,不重要。重要的是你的路径,路径。请打印你的路径,看看到底有没有那个图标文件!
  • __dirname,对于vue之类的来说,这个build前后,是会发生很大的变化的,所以使用__dirname就不合适了。

至于path.join是怎么回事,这里有篇文章:

关于__dirname__static的说明:

托盘图标一会就消失了

这个问题,似乎很诡异。其实就是你的写法问题,非全局变量会被定期回收。你的tray肯定是个函数内部的局部变量,而不是最顶层的全局变量。这就会导致,你的托盘被系统当成垃圾回收啦。就这么回事,所以把你的变量定义,提升到顶层即可。

请对比查看下面的两段代码,前者图标不会消失,后者图标过一会儿就会消失:

let tray = null
app.on('ready', () => {
  tray = new Tray(path.join(__dirname,"./favicon.png"));
  //...
})
app.on('ready', () => {
  let tray = new Tray(path.join(__dirname,"./favicon.png"));
  //...
})

总结

本文仅仅涉及到了electron创建托盘图标及上下文菜单的最基本姿势。在实际应用中,还是有更多相关特殊的托盘需求的。请关注苏南大叔的后续electron托盘相关文字:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   electron    tray