暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【十】Tauri 应用篇 - 应用菜单

浮之静 2022-07-27
590


此文以 macOS 为例子

Tauri 允许开发者创建自己的菜单项并向其添加特殊功能,枚举了特定于平台的菜单项集合(如 About
Hide
Quit
Copy
等,查看更多 MenuItem Variants[1]),目前版本(v1.0)未在 Windows 上实现。菜单主要包含以下 API:

  • Menu
    - 创建一个新菜单

  • Submenu
    - 使用给定的标题和菜单项创建一个新的子菜单

  • MenuItem
    - 菜单项,绑定到预定义的操作或 Custom
    发出事件

  • CustomMenuItem
    - 自定义菜单项

默认菜单

Step 1

新建 src-tauri/src/menu.rs
文件

use tauri::{utils::assets::EmbeddedAssets, Context, Menu};

pub fn init(context: &Context<EmbeddedAssets>) -> Menu {
// 获取应用名称
let name = &context.package_info().name;
tauri::Menu::os_default(name)
}

注意:不同 OS 下的默认菜单略有差别,详情请查看 Menu os_default[2]

Step 2

src-tauri/src/main.rs
中使用 menu.rs
,并将菜单添加至所有窗口

#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]


mod menu;

fn main() {
let context = tauri::generate_context!();
tauri::Builder::default()
.menu(menu::init(&context)) // ✅ 将菜单添加到所有窗口
.run(context)
.expect("error while running OhMyBox application");
}

自定义菜单

Menu
使用以下方式来添加一个菜单项目:

  • with_items
    - 使用给定的菜单项集合创建一个新菜单

    use tauri::{Menu, MenuItem, CustomMenuItem, Submenu};

    Menu::with_items([
    MenuItem::SelectAll.into(),
    #[cfg(target_os = "macos")]
    MenuItem::Redo.into(),
    CustomMenuItem::new("toggle", "Toggle visibility").into(),
    Submenu::new("View", Menu::new()).into(),
    ]);

  • add_native_item
    - 将原生菜单项添加到菜单

    use tauri::{Menu, MenuItem};

    Menu::new()
    .add_native_item(MenuItem::Copy)
    .add_native_item(MenuItem::Minimize)
    .add_native_item(MenuItem::Zoom);

  • add_item
    - 将自定义菜单项添加到菜单

    use tauri::{Menu, CustomMenuItem};

    Menu::new()
    .add_item(CustomMenuItem::new("quit".to_string(), "Quit"))
    .add_item(CustomMenuItem::new("close".to_string(), "Close"));

  • add_submenu
    - 添加一个带有子菜单的条目

    use tauri::{Menu, MenuItem, CustomMenuItem};

    Menu::new()
    .add_submenu(Submenu::new(
    "View", // 子菜单名称
    Menu::new() // 子菜单项
    .add_item(CustomMenuItem::new("close".to_string(), "Close")) // 自定义菜单(关闭)
    .add_native_item(MenuItem::Quit) // 原生菜单(退出)
    ));

菜单事件

原生菜单已绑定事件,无需再次绑定,自定义菜单则需要绑定事件

编辑 src-tauri/src/menu.rs
文件

use tauri::api::dialog::message;
use tauri::utils::assets::EmbeddedAssets;
use tauri::{AboutMetadata, Context, CustomMenuItem, Menu, MenuItem, Submenu, WindowMenuEvent};

// 应用菜单项
pub fn init(context: &Context<EmbeddedAssets>) -> Menu {
// 应用名称
let name = &context.package_info().name;
// tauri::Menu::os_default(name)
// 应用主菜单
let app_menu = Submenu::new(
"",
// MenuItem::About 为原生菜单
Menu::new().add_native_item(MenuItem::About(name.into(), AboutMetadata::new())),
);
// 文件菜单(自定义菜单)
let file_menu = Submenu::new(
"File",
Menu::new()
.add_item(CustomMenuItem::new("new_file".to_string(), "New File"))
.add_item(CustomMenuItem::new("edit_file".to_string(), "Edit File")),
);
// 编辑菜单(自定义菜单)
let edit_menu = Submenu::new(
"Edit",
Menu::new()
.add_item(CustomMenuItem::new("undo".to_string(), "Undo"))
.add_item(CustomMenuItem::new("redo".to_string(), "Redo")),
);

Menu::new()
.add_submenu(app_menu)
.add_submenu(file_menu)
.add_submenu(edit_menu)
}

// 应用菜单处理事件
pub fn handler(event: WindowMenuEvent) {
// 菜单所属的窗口
let win = Some(event.window());
// 匹配菜单 id
match event.menu_item_id() {
"new_file" => {
// debug 信息(终端输出)
dbg!("new file");
}
"edit_file" => {
// 发送信息到菜单所属窗口(弹窗形式)
message(win, "Eidt File", "TODO");
}
"undo" => {
dbg!("undo");
}
"redo" => {
dbg!("redo");
}
_ => {}
}
}

编辑 src-tauri/src/main.rs
文件

#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]


mod menu;

fn main() {
let context = tauri::generate_context!();
tauri::Builder::default()
.menu(menu::init(&context))
.on_menu_event(menu::handler)
.run(context)
.expect("error while running OhMyBox application");
}

更新菜单项

编辑 src-tauri/src/menu.rs
文件中的 handler
方法

pub fn handler(event: WindowMenuEvent) {
let win = Some(event.window());
let menu_handle = win.unwrap().menu_handle();
match event.menu_item_id() {
"new_file" => {
// 新开一个线程用于处理更新操作,否则应用会卡死
std::thread::spawn(move || {
menu_handle
.get_item("new_file") // 获取菜单项 id
.set_title("Create File") // 设置新的菜单名
.unwrap();
});
dbg!("new file");
}
"edit_file" => {
message(win, "Eidt File", "TODO");
}
"undo" => {
dbg!("undo");
}
"redo" => {
dbg!("redo");
}
_ => {}
}
}


注意:在 tauri::Builder::default().setup()
setup
中获取到 window 后也可以进行类似操作。关于菜单的更多信息,请自行查看文档 Tauri Menu[3]

References

[1]

MenuItem Variants: https://docs.rs/tauri/1.0.5/tauri/enum.MenuItem.html#variants

[2]

Menu os_default: https://docs.rs/tauri/1.0.5/tauri/struct.Menu.html#method.os_default

[3]

Tauri Menu: https://tauri.app/v1/guides/features/menu



文章转载自浮之静,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论