メニューがクリックされた時の処理を記述する方法について解説します。
Tauri v2 では、メニュー項目の作成時に action プロパティに関数を渡すだけで、簡単にイベントハンドラを定義できます (JavaScript)。
前提条件
Permissions (権限) の設定
src-tauri/capabilities/default.json に core:menu:default を追加します。
{
"permissions": [
...,
"core:menu:default"
]
}
1. フロントエンドで処理する (TypeScript)
action オプションを使用します。この関数はメニューがクリックされた時に呼び出され、引数として項目の id を受け取ります。
シンプルな記法(オブジェクト形式)
import { Menu } from '@tauri-apps/api/menu';
const handleMenuClick = (id: string) => {
console.log(`Common Handler: ${id}`);
};
const menu = await Menu.new({
items: [
{
id: 'open',
text: '開く',
action: (id) => {
console.log(`個別ハンドラ: ${id} がクリックされました`);
}
},
{
id: 'save',
text: '保存',
action: handleMenuClick // 関数参照を渡すことも可能
}
]
});
await menu.setAsAppMenu();
クラスを使用した記法
import { Menu, Submenu, MenuItem } from '@tauri-apps/api/menu';
// 1. 各メニュー項目を作成し、action を定義する
const openItem = await MenuItem.new({
id: 'open',
text: '開く',
action: (id) => {
console.log(`Action Handler: ${id} がクリックされました`);
}
});
const saveItem = await MenuItem.new({
id: 'save',
text: '保存',
action: (id) => {
console.log(`Action Handler: ${id} がクリックされました`);
}
});
// 2. サブメニューを作成し、項目を追加する
const fileSubmenu = await Submenu.new({
text: 'ファイル',
items: [openItem, saveItem]
});
// 3. メニューを作成し、サブメニューを追加する
const menu = await Menu.new({
items: [fileSubmenu]
});
// 4. アプリケーションメニューとして設定する
await menu.setAsAppMenu();
参考: MenuItemOptions API リファレンス
2. バックエンドで処理する (Rust)
Rust 側でメニューイベントをハンドリングするには、tauri::Builder の on_menu_event を使用します。
MenuBuilder を使用した記法
use tauri::menu::MenuBuilder;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let menu = MenuBuilder::new(app)
.text("open", "開く")
.text("save", "保存")
.build()?;
app.set_menu(menu)?;
Ok(())
})
.on_menu_event(|app, event| {
match event.id().0.as_str() {
"open" => {
println!("Open clicked");
// フロントエンドにイベントを送信する等の処理
// app.emit("open-requested", ()).unwrap();
}
"save" => {
println!("Save clicked");
}
_ => {}
}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
補足
* イベントの競合: フロントエンド (action) とバックエンド (on_menu_event) の両方で処理を書いた場合、バックエンドのイベントハンドラは常に発火しますが、フロントエンドの action はフロントエンドで作成されたメニュー項目に対してのみ機能します。
* 推奨: フロントエンド中心のロジックであれば TypeScript の action を、システム操作やウィンドウ制御などが必要な場合は Rust の on_menu_event を使用すると良いでしょう。