跳到内容
Tauri

窗口菜单

原生应用程序菜单可以附加到窗口或系统托盘。在桌面端可用。

要创建基础的原生窗口菜单并将其附加到窗口,您可以创建各种类型的菜单项,包括基本项、复选框项和分隔符。

使用 Menu.new 静态函数创建窗口菜单。

import { Menu } from '@tauri-apps/api/menu';
const menu = await Menu.new({
items: [
{
id: 'quit',
text: 'Quit',
action: () => {
console.log('quit pressed');
},
},
{
id: 'check_item',
text: 'Check Item',
checked: true,
},
{
type: 'Separator',
},
{
id: 'disabled_item',
text: 'Disabled Item',
enabled: false,
},
{
id: 'status',
text: 'Status: Processing...',
},
],
});
// If a window was not created with an explicit menu or had one set explicitly,
// this menu will be assigned to it.
menu.setAsAppMenu().then(async (res) => {
console.log('menu set success', res);
// Update individual menu item text
const statusItem = await menu.get('status');
if (statusItem) {
await statusItem.setText('Status: Ready');
}
});

每个自定义菜单项在点击时都会触发一个事件。使用 on_menu_event API 来处理它们。

import { Menu } from '@tauri-apps/api/menu';
const menu = await Menu.new({
items: [
{
id: 'Open',
text: 'open',
action: () => {
console.log('open pressed');
},
},
{
id: 'Close',
text: 'close',
action: () => {
console.log('close pressed');
},
},
],
});
await menu.setAsAppMenu();

多级菜单允许您将菜单项按“文件”、“编辑”等类别分组。这些菜单项将作为应用程序窗口的一部分显示在 Windows 或 Linux 上,或者在 macOS 的菜单栏中显示。

注意:在 macOS 上使用子菜单时,所有项必须分组在一个子菜单下。顶级项将被忽略。此外,第一个子菜单将默认放置在应用程序的“关于”菜单下,无论 text 标签是什么。您应该将一个子菜单作为第一个条目(例如,“关于”子菜单)来填充此空间。

import { Menu, MenuItem, Submenu } from '@tauri-apps/api/menu';
// Will become the application submenu on MacOS
const aboutSubmenu = await Submenu.new({
text: 'About',
items: [
await MenuItem.new({
id: 'quit',
text: 'Quit',
action: () => {
console.log('Quit pressed');
},
}),
],
});
const fileSubmenu = await Submenu.new({
text: 'File',
icon: 'folder', // Optional: Add an icon to the submenu
items: [
await MenuItem.new({
id: 'new',
text: 'New',
action: () => {
console.log('New clicked');
},
}),
await MenuItem.new({
id: 'open',
text: 'Open',
action: () => {
console.log('Open clicked');
},
}),
await MenuItem.new({
id: 'save_as',
text: 'Save As...',
action: () => {
console.log('Save As clicked');
},
}),
],
});
const editSubmenu = await Submenu.new({
text: 'Edit',
items: [
await MenuItem.new({
id: 'undo',
text: 'Undo',
action: () => {
console.log('Undo clicked');
},
}),
await MenuItem.new({
id: 'redo',
text: 'Redo',
action: () => {
console.log('Redo clicked');
},
}),
],
});
const menu = await Menu.new({
items: [aboutSubmenu, fileSubmenu, editSubmenu],
});
menu.setAsAppMenu();
// You can also update the submenu icon dynamically
fileSubmenu.setIcon('document');
// Or set a native icon (only one type applies per platform)
fileSubmenu.setNativeIcon('NSFolder');

使用内置(原生)菜单项,这些菜单项具有操作系统或 Tauri 预定义行为。

import { Menu, PredefinedMenuItem } from '@tauri-apps/api/menu';
const copy = await PredefinedMenuItem.new({
text: 'copy-text',
item: 'Copy',
});
const separator = await PredefinedMenuItem.new({
text: 'separator-text',
item: 'Separator',
});
const undo = await PredefinedMenuItem.new({
text: 'undo-text',
item: 'Undo',
});
const redo = await PredefinedMenuItem.new({
text: 'redo-text',
item: 'Redo',
});
const cut = await PredefinedMenuItem.new({
text: 'cut-text',
item: 'Cut',
});
const paste = await PredefinedMenuItem.new({
text: 'paste-text',
item: 'Paste',
});
const select_all = await PredefinedMenuItem.new({
text: 'select_all-text',
item: 'SelectAll',
});
const menu = await Menu.new({
items: [copy, separator, undo, redo, cut, paste, select_all],
});
await menu.setAsAppMenu();

如果您想更改菜单的状态,例如文本、图标或选中状态,您可以再次调用 set_menu

import {
Menu,
CheckMenuItem,
IconMenuItem,
MenuItem,
} from '@tauri-apps/api/menu';
import { Image } from '@tauri-apps/api/image';
let currentLanguage = 'en';
const check_sub_item_en = await CheckMenuItem.new({
id: 'en',
text: 'English',
checked: currentLanguage === 'en',
action: () => {
currentLanguage = 'en';
check_sub_item_en.setChecked(currentLanguage === 'en');
check_sub_item_zh.setChecked(currentLanguage === 'cn');
console.log('English pressed');
},
});
const check_sub_item_zh = await CheckMenuItem.new({
id: 'zh',
text: 'Chinese',
checked: currentLanguage === 'zh',
action: () => {
currentLanguage = 'zh';
check_sub_item_en.setChecked(currentLanguage === 'en');
check_sub_item_zh.setChecked(currentLanguage === 'zh');
check_sub_item_zh.setAccelerator('Ctrl+L');
console.log('Chinese pressed');
},
});
// Load icon from path
const icon = await Image.fromPath('../src/icon.png');
const icon2 = await Image.fromPath('../src/icon-2.png');
const icon_item = await IconMenuItem.new({
id: 'icon_item',
text: 'Icon Item',
icon: icon,
action: () => {
icon_item.setIcon(icon2);
console.log('icon pressed');
},
});
const text_item = await MenuItem.new({
id: 'text_item',
text: 'Text Item',
action: () => {
text_item.setText('Text Item Changed');
console.log('text pressed');
},
});
const menu = await Menu.new({
items: [
{
id: 'change menu',
text: 'change_menu',
items: [text_item, check_sub_item_en, check_sub_item_zh, icon_item],
},
],
});
await menu.setAsAppMenu();

© 2025 Tauri 贡献者。CC-BY / MIT