告别任务栏杂乱:Electron应用托盘化完整实现指南

告别任务栏杂乱:Electron应用托盘化完整实现指南

【免费下载链接】electron-quick-start Clone to try a simple Electron app 【免费下载链接】electron-quick-start 项目地址: https://gitcode.com/gh_mirrors/el/electron-quick-start

你是否也曾被任务栏上密密麻麻的窗口图标困扰?工作时需要同时打开多个应用,导致任务栏拥挤不堪,寻找目标窗口如同大海捞针?本文将带你一步步实现Electron应用的托盘化(Tray)功能,让你的应用优雅地常驻系统托盘,随时待命却不占用任务栏空间。

读完本文,你将学会:

  • 如何为Electron应用添加系统托盘图标
  • 设计实用的托盘上下文菜单
  • 实现窗口的隐藏/显示切换逻辑
  • 处理不同操作系统下的托盘行为差异

准备工作

在开始之前,请确保你已获取项目代码:

git clone https://gitcode.com/gh_mirrors/el/electron-quick-start
cd electron-quick-start
npm install

项目基础结构如下:

托盘功能实现步骤

1. 引入Tray和Menu模块

首先需要修改main.js,引入Electron的Tray(托盘)和Menu(菜单)模块。在文件顶部的模块引入部分添加以下代码:

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

2. 创建托盘图标

在创建主窗口的代码之后,添加托盘初始化逻辑。我们需要准备一个图标文件(建议使用.png格式,尺寸为16x16或32x32像素),并将其放置在项目目录中。

let tray = null;

function createWindow () {
  // 已有的窗口创建代码...
  
  // 创建托盘图标
  const iconPath = path.join(__dirname, 'tray-icon.png');
  tray = new Tray(iconPath);
  
  // 设置托盘悬停提示
  tray.setToolTip('Electron托盘应用示例');
}

3. 设计托盘上下文菜单

为托盘图标添加右键菜单,实现常用功能的快速访问。在main.js中添加菜单创建代码:

function createTrayMenu() {
  const contextMenu = Menu.buildFromTemplate([
    { 
      label: '显示窗口', 
      click: () => {
        mainWindow.show();
      }
    },
    { 
      label: '隐藏窗口', 
      click: () => {
        mainWindow.hide();
      }
    },
    { type: 'separator' }, // 分隔线
    { 
      label: '退出应用', 
      click: () => {
        app.quit();
      }
    }
  ]);
  
  tray.setContextMenu(contextMenu);
}

4. 实现窗口显示/隐藏切换

为了让用户点击托盘图标时能够快速切换窗口的显示和隐藏状态,我们需要为托盘图标添加点击事件监听:

// 在创建托盘之后添加
tray.on('click', () => {
  if (mainWindow.isVisible()) {
    mainWindow.hide();
  } else {
    mainWindow.show();
  }
});

5. 处理窗口关闭事件

默认情况下,关闭窗口会导致应用退出。我们需要修改窗口关闭事件,让窗口关闭时只隐藏到托盘而不退出应用:

mainWindow.on('close', (event) => {
  // 取消默认的关闭行为
  event.preventDefault();
  // 隐藏窗口
  mainWindow.hide();
  // 可选:显示系统通知提示应用已最小化到托盘
  if (appNotificationSupported) {
    new Notification({
      title: '应用已最小化',
      body: '应用已最小化到系统托盘,点击图标恢复。'
    }).show();
  }
});

完整实现代码

修改后的main.js完整代码如下:

// Modules to control application life and create native browser window
const { app, BrowserWindow, Tray, Menu } = require('electron')
const path = require('node:path')

let mainWindow;
let tray = null;

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  // and load the index.html of the app.
  mainWindow.loadFile('index.html')

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()
  
  // 创建托盘
  createTray();
}

function createTray() {
  // 确保图标文件存在,这里使用了项目中的示例图标
  const iconPath = path.join(__dirname, 'tray-icon.png');
  tray = new Tray(iconPath);
  
  // 设置托盘提示
  tray.setToolTip('Electron托盘应用示例');
  
  // 创建上下文菜单
  const contextMenu = Menu.buildFromTemplate([
    { 
      label: '显示窗口', 
      click: () => {
        mainWindow.show();
      }
    },
    { 
      label: '隐藏窗口', 
      click: () => {
        mainWindow.hide();
      }
    },
    { type: 'separator' },
    { 
      label: '退出应用', 
      click: () => {
        // 彻底退出应用前清理托盘
        tray.destroy();
        app.quit();
      }
    }
  ]);
  
  tray.setContextMenu(contextMenu);
  
  // 点击托盘图标切换窗口显示/隐藏
  tray.on('click', () => {
    if (mainWindow.isVisible()) {
      mainWindow.hide();
    } else {
      mainWindow.show();
    }
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
  // 修改默认行为,所有窗口关闭时不退出应用
  // if (process.platform !== 'darwin') app.quit()
})

// 自定义窗口关闭事件
mainWindow.on('close', (event) => {
  event.preventDefault();
  mainWindow.hide();
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

操作系统兼容性处理

不同操作系统对系统托盘的行为有不同的规范,需要针对性处理:

Windows系统

  • 托盘图标位于任务栏右侧的系统托盘区域
  • 支持气泡通知
  • 通常需要按住Ctrl键点击才能显示所有托盘图标

macOS系统

  • 托盘图标位于屏幕右上角的菜单栏
  • 应用通常同时保留Dock图标
  • 可以通过app.dock.hide()隐藏Dock图标

Linux系统

  • 行为因桌面环境而异(GNOME、KDE等)
  • 可能需要安装额外的托盘支持扩展

添加跨平台处理代码到main.js

// 在createWindow函数中添加
if (process.platform === 'darwin') {
  // macOS: 隐藏Dock图标
  app.dock.hide();
} else if (process.platform === 'win32') {
  // Windows: 设置窗口关闭按钮行为
  mainWindow.on('close', (event) => {
    event.preventDefault();
    mainWindow.hide();
    // 显示系统通知
    new Notification({
      title: '应用已最小化',
      body: '应用已最小化到系统托盘,点击图标恢复。'
    }).show();
  });
}

测试与运行

完成以上修改后,运行应用测试托盘功能:

npm start

你应该能看到应用窗口和系统托盘区域出现的应用图标。尝试:

  1. 点击托盘图标切换窗口显示/隐藏
  2. 右键点击托盘图标打开上下文菜单
  3. 关闭窗口,确认应用是否最小化到托盘而非退出

总结与进阶

通过本文的步骤,你已经成功为Electron应用添加了托盘功能。这不仅能让你的应用更加用户友好,还能提升用户体验,减少任务栏杂乱。

进阶探索方向:

  • 为托盘图标添加徽章(Badge)显示未读消息数
  • 实现托盘图标的动画效果
  • 根据应用状态动态更换托盘图标
  • 添加键盘快捷键控制窗口显示/隐藏

更多Electron API细节,请参考官方文档:Electron Tray文档

希望本文能帮助你打造更优雅的Electron应用。如果觉得有用,请点赞收藏,关注获取更多Electron开发技巧!

【免费下载链接】electron-quick-start Clone to try a simple Electron app 【免费下载链接】electron-quick-start 项目地址: https://gitcode.com/gh_mirrors/el/electron-quick-start

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

抵扣说明:

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

余额充值