人人都会AI编程

13.1 系统托盘(Tray):托盘图标、右键菜单、事件响应

更新时间:2026-07-11

系统托盘是桌面应用常驻后台、提供快捷操作的经典入口。Tauri 对系统托盘的支持非常完善,你可以轻松实现托盘图标、右键菜单以及各类事件响应,而且所有配置都可以通过 Rust 代码清晰完成。


创建一个基础托盘

在 Tauri 2 中,托盘功能通过 tauri::tray::TrayIconBuilder 构建。通常在主 lib.rsmain.rssetup 阶段初始化:

use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent};

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 初始化托盘
            let _tray = TrayIconBuilder::new()
                .icon(app.default_window_icon().cloned().unwrap()) // 使用应用图标
                .tooltip("我的 Tauri 应用")
                .on_tray_icon_event(|tray, event| match event {
                    TrayIconEvent::Click {
                        button: MouseButton::Left,
                        button_state: MouseButtonState::Up,
                        ..
                    } => {
                        // 左键点击:显示/隐藏主窗口
                        let window = tray.app_handle().get_webview_window("main").unwrap();
                        if window.is_visible().unwrap() {
                            window.hide().unwrap();
                        } else {
                            window.show().unwrap();
                            window.set_focus().unwrap();
                        }
                    }
                    _ => {}
                })
                .build(app)?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("启动应用失败");
}

右键菜单

为托盘添加菜单非常直观,可以组合多个菜单项,并绑定事件:

let tray = TrayIconBuilder::new()
    .icon(app.default_window_icon().cloned().unwrap())
    .menu(
        tauri::menu::Menu::with_items(app, &[
            &tauri::menu::MenuItem::with_id(app, "show", "显示主窗口", true, None::<&str>)?,
            &tauri::menu::PredefinedMenuItem::separator(app)?,
            &tauri::menu::MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?,
        ])
        .unwrap(),
    )
    .on_menu_event(|app, event| {
        match event.id().as_ref() {
            "show" => {
                if let Some(window) = app.get_webview_window("main") {
                    window.show().unwrap();
                    window.set_focus().unwrap();
                }
            }
            "quit" => {
                app.exit(0);
            }
            _ => {}
        }
    })
    .build(app)?;

常用事件响应

on_tray_icon_event 可以精确捕获鼠标事件,你可以根据需求定制:

  • 左键单击:常用于切换主窗口显隐。
  • 右键单击:通常会自动弹出菜单(如果设置了菜单),但你也可以覆盖为自定义行为。
  • 双击:可用于快速截屏、打开特定功能等。
.on_tray_icon_event(|tray, event| {
    if let TrayIconEvent::DoubleClick { .. } = event {
        // 双击事件:比如打开偏好设置
    }
})

实用技巧

  1. 窗口关闭时最小化到托盘

拦截窗口关闭事件,改为隐藏而非退出:

   .on_window_event(|window, event| {
       if let tauri::WindowEvent::CloseRequested { .. } = event {
           window.hide().unwrap(); // 隐藏到托盘
           // 需要手动阻止默认关闭行为(设置 prevent_close = true)
       }
   })
   

并在 Cargo.toml 中开启 window.close 权限,配置中设置 "close": true

  1. 应用退出时清理托盘

托盘对象在 Drop 时会自动移除,因此只需保证其生命周期长于应用运行期即可。

  1. 托盘图标格式

推荐使用 .png.ico 文件,通过 tauri::Icon 加载。对于不同平台,理想尺寸为 16×16 至 64×64 像素。

注意事项

  • Linux 桌面环境差异:部分 Linux 环境可能不完全支持托盘图标或菜单行为,测试时需覆盖 GNOME、KDE 等主流桌面。
  • macOS 权限:若托盘需要显示菜单,无需额外权限;如果要启动守护进程或持续后台,可能需要检查 App Sandbox 设置。

系统托盘虽小,但能大幅提升桌面应用的“驻留感”和用户体验。Tauri 将托盘操作抽象得足够简单且跨平台一致,值得在工具类应用里优先实现。