上一篇我们使用tauri创建的应用的基础操作,这一篇我们主要讲一下tauri的菜单,系统托盘和进程之间的通信等操作
创建体积更小、运行更快、更加安全的跨平台桌面应用——初步了解Tauri
菜单
tauri的菜单可以使用系统的菜单也可以自定义菜单
mac系统支持的比较好有很多,相比windows和Linux支持就相对少了一些
Windows:
File
CloseWindow
Quit
Edit
Cut
Copy
Paste
Window
Minimize
CloseWindow
Linux:
File
CloseWindow
Quit
Window
Minimize
CloseWindow
macOS:
App
About
Separator
Services
Separator
Hide
HideOthers
ShowAll
Separator
Quit
File
CloseWindow
Edit
Undo
Redo
Separator
Cut
Copy
Paste
SelectAll
View
EnterFullScreen
Window
Minimize
Zoom
Separator
CloseWindow
系统菜单
系统菜单
通过add_native_item方法添加系统菜单,例如添加复制菜单
Menu::new().add_native_item(MenuItem::Copy)
自定义菜单
通过add_native_item方法添加系统菜单,例如添加退出登录的自定义菜单
Menu::new().add_item(CustomMenuItem::new("logout".to_string(), "退出登录"))
通过accelerator方法给自定义菜单添加快捷键 例如添加重新加载的自定义菜单 并通过Cmd+R的快捷键触发
Menu::new()
.add_item(
CustomMenuItem::new("reload".to_string(), "重新加载")
.accelerator("CmdOrCtrl+R")
.into(),
)
自定义菜单需要添加监听自定义菜单事件来执行相关操作
tauri::Builder::default()
// 添加菜单
.menu(menus)
// 监听自定义菜单事件
.on_menu_event(|event| match event.menu_item_id() {
// 退出app
"quit" => {
std::process::exit(0);
}
// 关闭窗口
"close" => {
event.window().close().unwrap();
}
// 向客户端广播刷新事件
"reload" => event
.window()
.app_handle()
.emit_all("event-reload", Payload {})
.unwrap(),
系统托盘
系统托盘的使用和菜单比较类似,也是需要添加相关操作和监听自定义菜单事件来执行相关操作
let quit = CustomMenuItem::new("quit".to_string(), "退出");
let close = CustomMenuItem::new("close".to_string(), "关闭窗口");
let hide = CustomMenuItem::new("hide".to_string(), "隐藏窗口");
let tray_menu = SystemTrayMenu::new()
.add_item(hide)
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(close)
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(quit);
tauri::Builder::default()
.system_tray(SystemTray::new().with_menu(tray_menu))
进程间通信
rust向js广播事件 通过appHandle的emit_all方法实现的
"reload" => event
.window()
.app_handle()
.emit_all("event-reload", Payload {})
.unwrap(),
js注册事件接受广播
// 导入 listen 方法 监听事件
import { listen } from '@tauri-apps/api/event'
listen('event-reload', () => {
window.location.reload()
})
js向rust广播事件
// 导入 invoke 方法
import { invoke } from '@tauri-apps/api/tauri'
// 添加监听函数,监听 DOM 内容加载完成事件
document.addEventListener('DOMContentLoaded', () => {
// DOM 内容加载完成之后,通过 invoke 调用 在 Rust 中已经注册的命令
invoke('close_splashscreen')
})
rust注册事件接受广播
tauri::Builder::default()
// 注册命令
.invoke_handler(tauri::generate_handler![close_splashscreen])
完整代码
src-tauri\main.rs 完整代码如下
use tauri::{
CustomMenuItem, Manager, Menu, MenuItem, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu,
SystemTrayMenuItem,
};
#[derive(Clone, serde::Serialize)]
struct Payload {}
fn main() {
let submenu_app = Submenu::new(
"Turbo's 笔记",
Menu::new()
.add_item(CustomMenuItem::new("about".to_string(), "检查版本"))
.add_native_item(MenuItem::Separator)
.add_item(
CustomMenuItem::new("hide".to_string(), "隐藏 Turbo's 笔记")
.accelerator("CmdOrCtrl+H")
.into(),
)
.add_item(
CustomMenuItem::new("show".to_string(), "显示 Turbo's 笔记")
.accelerator("CmdOrCtrl+S")
.into(),
)
.add_native_item(MenuItem::Separator)
.add_item(
CustomMenuItem::new("quit".to_string(), "退出")
.accelerator("CmdOrCtrl+Q")
.into(),
),
);
let submenu_edit = Submenu::new(
"编辑",
Menu::new()
.add_native_item(MenuItem::Redo)
.add_native_item(MenuItem::Undo)
.add_native_item(MenuItem::Separator)
.add_native_item(MenuItem::Cut)
.add_native_item(MenuItem::Copy)
.add_native_item(MenuItem::Paste),
);
let submenu_view = Submenu::new(
"视图",
Menu::new()
.add_item(
CustomMenuItem::new("reload".to_string(), "重新加载")
.accelerator("CmdOrCtrl+R")
.into(),
)
.add_item(
CustomMenuItem::new("logout".to_string(), "退出登录")
.accelerator("Alt+CmdOrCtrl+Q")
.into(),
),
);
let menus = Menu::new()
.add_submenu(submenu_app)
.add_submenu(submenu_edit)
.add_submenu(submenu_view);
let quit = CustomMenuItem::new("quit".to_string(), "退出");
let close = CustomMenuItem::new("close".to_string(), "关闭窗口");
let hide = CustomMenuItem::new("hide".to_string(), "隐藏窗口");
let tray_menu = SystemTrayMenu::new()
.add_item(hide)
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(close)
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(quit);
tauri::Builder::default()
.system_tray(SystemTray::new().with_menu(tray_menu))
.on_system_tray_event(|app, event| menu_handle(app, event))
// 添加菜单
.menu(menus)
// 监听自定义菜单事件
.on_menu_event(|event| match event.menu_item_id() {
"about" => event
.window()
.app_handle()
.emit_all("event-about", Payload {})
.unwrap(),
"quit" => {
std::process::exit(0);
}
"close" => {
event.window().close().unwrap();
}
"hide" => {
event.window().hide().unwrap();
}
"show" => {
event.window().show().unwrap();
}
"logout" => event
.window()
.app_handle()
.emit_all("event-logout", Payload {})
.unwrap(),
"reload" => event
.window()
.app_handle()
.emit_all("event-reload", Payload {})
.unwrap(),
_ => {}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
fn menu_handle(app_handle: &tauri::AppHandle, event: SystemTrayEvent) {
match event {
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
"quit" => {
std::process::exit(0);
}
"close" => {
let window = app_handle.get_window("main").unwrap();
window.close().unwrap();
}
"hide" => {
let item_handle = app_handle.tray_handle().get_item(&id);
let window = app_handle.get_window("main").unwrap();
if window.is_visible().unwrap() {
window.hide().unwrap();
item_handle.set_title("显示窗口").unwrap();
} else {
window.show().unwrap();
item_handle.set_title("隐藏窗口").unwrap();
}
}
_ => {}
},
_ => {}
}
}