チェックボックス付きのメニュー項目を作る

Recipe ID: menu-003

チェックボックス付きのメニュー項目(トグルスイッチのような機能)を作成する方法を解説します。

「表示/非表示」の切り替えや、設定の ON/OFF など、状態を持つメニュー項目を作るのに最適です。

前提条件

Permissions (権限) の設定

src-tauri/capabilities/default.jsonmenu:default を追加します。

{
  "permissions": [
    ...,
    "core:menu:default"
  ]
}

1. フロントエンドから追加する (TypeScript)

シンプルな記法(オブジェクト形式)

オブジェクト形式で checked: true を指定すると、自動的にチェック項目として認識されます。

import { Menu } from '@tauri-apps/api/menu';

const menu = await Menu.new({
  items: [
    {
      text: '表示',
      items: [
        {
          id: 'toggle',
          text: '状態切替',
          checked: true // trueを指定するとチェック項目になる
        }
      ]
    }
  ]
});

await menu.setAsAppMenu();

CheckMenuItem クラスを使用した記法

CheckMenuItem.new クラスを使用して明示的にチェック項目を作成することもできます。

import { Menu, Submenu, CheckMenuItem } from '@tauri-apps/api/menu';

// 1. チェック項目の作成
const item = await CheckMenuItem.new({
  id: 'toggle',
  text: '状態切替',
  checked: true,
  action: (id) => {
    console.log(`Toggled: ${id}`);
  }
});

// 2. メニューに組み込み
const menu = await Menu.new({
  items: [
    await Submenu.new({
      text: '表示',
      items: [item]
    })
  ]
});
await menu.setAsAppMenu();

チェック状態の取得・変更

// 状態の確認
const isChecked = await item.isChecked();
console.log(`状態は ${isChecked ? 'ON' : 'OFF'} です`);

// 状態の変更
await item.setChecked(false);

参考: CheckMenuItem API リファレンス

2. バックエンドから追加する (Rust)

MenuBuilder を使用した記法(推奨)

use tauri::menu::{MenuBuilder, SubmenuBuilder};

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            let toggle_menu = SubmenuBuilder::new(app, "表示")
                .check("toggle", "状態切替") // 名前とテキストを指定
                .build()?;

            let menu = MenuBuilder::new(app).item(&toggle_menu).build()?;
            app.set_menu(menu)?;
            Ok(())
        })
        .on_menu_event(|_app, event| {
            if event.id() == "toggle" {
                 println!("トグルされました");
            }
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

CheckMenuItem を個別に作成する記法

use tauri::menu::{CheckMenuItem, Menu, Submenu};

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            let handle = app.handle();
            
            // 1. チェック項目の作成
            let item = CheckMenuItem::with_id(
                handle, "toggle", "状態切替", 
                true, // enabled
                true, // checked
                None::<&str>
            )?;

            // 2. メニューに組み込み
            let submenu = Submenu::with_items(handle, "表示", true, &[&item])?;
            let menu = Menu::with_items(handle, &[&submenu])?;
            app.set_menu(menu)?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

チェック状態を取得・変更する

use tauri::menu::{CheckMenuItem, Menu, Submenu};
use tauri::{State, Manager}; // Managerトレイトが必要

// 1. 状態を保持するための構造体
struct MenuState(CheckMenuItem<tauri::Wry>);

// 2. フロントエンドから呼び出すコマンド
#[tauri::command]
fn toggle_status(state: State<'_, MenuState>) -> tauri::Result<()> {
    let item = &state.0;
    
    // 状態を取得・変更
    let is_checked = item.is_checked()?;
    println!("現在の状態: {}", is_checked);
    item.set_checked(!is_checked)?;
    
    Ok(())
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            let handle = app.handle();
            
            // アイテムを作成
            let item = CheckMenuItem::with_id(
                handle, "toggle", "状態切替", 
                true, true, None::<&str>
            )?;

            // ★ Stateとして登録(これでコマンドからアクセス可能になります)
            app.manage(MenuState(item.clone()));

            // メニューに組み込み
            let submenu = Submenu::with_items(handle, "表示", true, &[&item])?;
            let menu = Menu::with_items(handle, &[&submenu])?;
            app.set_menu(menu)?;
            Ok(())
        })
        // ★ コマンドを登録
        .invoke_handler(tauri::generate_handler![toggle_status])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

補足

* 自動トグル: チェックメニュー項目はクリックされると自動的にチェック状態が反転します。
* 状態の永続化: アプリ再起動後もチェック状態を維持したい場合は、設定ファイルなどに保存し、起動時に読み込む処理が必要です。