自古以来,对于桌面应用,系统托盘是不可缺少的一部分。tauri 2 也是一样。
官网文档:https://v2.tauri.app/learn/system-tray/
参考博客:https://blog.csdn.net/xiaoyuanbaobao/article/details/143781484
对于 tarui 2,很多服务端的功能,前端也可以实现。它会提供一套 api,使得前端可以构建服务端的能力。当然,也可以在服务端去实现,然后用前端去调用。
简单记录一下
有上边的文档和博客,就可以完成基础的托盘创建。这里做以下简单的记录。
src-tauri/Cargo.toml
中修改配置tauri = { version = "2", features = ["tray-icon", "image-png"] }
。 这里增加了一个 image-png 配置。
2.后边如果运行报错。 error: failed to select a version for the requirement image = "^0.25"
candidate versions found which didn't match: 0.24.7, 0.24.6, 0.24.5, ...
location searched: crates.io index 时,就在 src-tauri/Cargo.toml
中追加配置。
[dependencies]
image = "^0.25"
tauri = { version = "2", features = ["tray-icon", "image-png"] }
3.权限设置。系统托盘往往会操作窗体的显示和程序的退出。这些都需要配置权限。在 src-tauri/capabilities/default.json
中,增加以下配置。
"core:window:allow-set-focus",
"core:window:allow-close",
"core:window:allow-is-visible",
"core:window:allow-unmaximize",
"core:window:allow-unminimize",
"core:window:allow-minimize"
加上之前的,完整的 default.json
文件长这样。
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": [
"main"
],
"permissions": [
"core:default",
"shell:allow-open",
{
"identifier": "http:default",
"allow": [
{
"url": "http://digitalai.dabaoensi.com:8181/"
},
{
"url": "https://www.yuepaibao.com/"
}
],
"deny": [
{
"url": "https://private.tauri.app"
}
]
},
"core:webview:allow-create-webview",
"core:window:allow-show",
"core:window:allow-set-fullscreen",
"core:webview:allow-create-webview-window",
"core:webview:allow-webview-close",
"process:default",
"core:window:allow-set-focus",
"core:window:allow-close",
"core:window:allow-is-visible",
"core:window:allow-unmaximize",
"core:window:allow-unminimize",
"core:window:allow-minimize"
]
}
上边这些配置好了。就开始写代码了。
创建 src/utils/tray.ts 文件。把上边博客中的代码复制过来。
// 获取当前窗口
import { getCurrentWindow } from '@tauri-apps/api/window';
// 导入系统托盘
import { TrayIcon, TrayIconOptions, TrayIconEvent } from '@tauri-apps/api/tray';
// 托盘菜单
import { Menu, MenuOptions } from '@tauri-apps/api/menu';
// 进程管理
import { exit } from '@tauri-apps/plugin-process';
/**
* 在这里你可以添加一个托盘菜单,标题,工具提示,事件处理程序等
*/
const options: TrayIconOptions = {
// icon 的相对路径基于:项目根目录/src-tauri/,其他 tauri api 相对路径大抵都是这个套路
icon: "icons/32x32.png",
// 托盘提示,悬浮在托盘图标上可以显示 tauri-app
tooltip: '大报恩寺',
// 是否在左键点击时显示托盘菜单,默认为 true。当然不能为 true 啦,程序进入后台不得左键点击图标显示窗口啊。
menuOnLeftClick: false,
// 托盘图标上事件的处理程序。
action: (event: TrayIconEvent) => {
// 左键点击事件
if (event.type === 'Click' && event.button === "Left" && event.buttonState === 'Down') {
console.log('单击事件');
// 显示窗口
winShowFocus();
}
}
}
/**
* 窗口置顶显示
*/
async function winShowFocus() {
// 获取窗体实例
const win = getCurrentWindow();
// 检查窗口是否见,如果不可见则显示出来
if (!(await win.isVisible())) {
win.show();
} else {
// 检查是否处于最小化状态,如果处于最小化状态则解除最小化
if (await win.isMinimized()) {
await win.unminimize();
}
// 窗口置顶
await win.setFocus();
}
}
/**
* 创建托盘菜单
*/
async function createMenu() {
return await Menu.new({
// items 的显示顺序是倒过来的
items: [
{
id: 'show',
text: '显示窗口',
action: () => {
winShowFocus();
}
},
{
// 菜单 id
id: 'quit',
// 菜单文本
text: '退出',
// 菜单项点击事件
action: () => {
console.log('退出')
// 退出应用
exit(0);
}
}
]
})
}
/**
* 创建系统托盘
*/
export async function createTray() {
// 获取 menu
options.menu = await createMenu();
await TrayIcon.new(options);
}
然后,就是使用了。 在 App.vue 中。增加以下代码。
<script setup lang="ts">
import { createTray } from './utils/tray'
createTray()
.then(() => {
console.log("sucess");
})
.catch((error: any) => {
console.log("error", error);
});
</script>
最后执行 pnpm tauri dev
来运行,试试效果。如果一切正常,表示是 ok。如果有问题,遇到问题就要解决问题,直到成功为止。
零代码托盘
可以直接在 src-tauri/tauri.conf.json
中增加配置,来实现托盘。只是这个托盘仅仅是个托盘,没有任何交互和右键菜单。追加配置如下:
{
"app": {
"windows": [
{
"title": "南京大报恩寺",
"width": 540,
"height": 960
}
],
"security": {
"csp": null
},
"trayIcon": {
"iconPath": "icons/icon.png",
"iconAsTemplate": true,
"title": "大报恩寺",
"tooltip": "大报恩寺"
}
},
}
就是在 app 节点下增加 trayIcon 配置即可。如果配置了这个,代码实现的托盘就无效了。
美观优化
好看的托盘菜单都会有 icon 和 文字一起组合构成,这样才更好看。看 MenuOptions 的 items。它的类型有 MenuItem, IconMenuItem 等构成。其中 IconMenuItem 就是有 icon 的菜单。
/** List of items to add to the new menu. */
items?: Array<Submenu | MenuItem | PredefinedMenuItem | CheckMenuItem | IconMenuItem | MenuItemOptions | SubmenuOptions | IconMenuItemOptions | PredefinedMenuItemOptions | CheckMenuItemOptions>;
去 https://www.iconfont.cn 中,找一个适合的 icon,以 png 格式下载下来。宽高 32*32 就可以。文件放在 src-tauri/assets/image/tray/exit.png
这里。修改原来的 tray.ts 代码。
{
// 菜单 id
id: 'quit',
// 菜单文本
text: '退出',
icon: 'assets/image/tray/exit.png',
// 菜单项点击事件
action: () => {
console.log('退出')
// 退出应用
exit(0);
}
}
就是增加了一个 icon,属性,配置好图片路径就可以。
对应 ts 类型
https://v2.tauri.app/reference/javascript/api/namespacetray/#new