---
sidebar_position: 4
---

# 应用菜单

可以通过定义[菜单](#菜单)结构类型并调用运行时方法[设置应用程序菜单](/docs/reference/runtime/menu#设置应用程序菜单)向 Wails 项目添加应用程序菜单。

也可以通过更新菜单结构并调用[更新应用程序菜单](/docs/reference/runtime/menu#更新应用程序菜单)来动态更新菜单 。

示例:

```go
	myMenu := menu.NewMenuFromItems(
		menu.SubMenu("File", menu.NewMenuFromItems(
			menu.Text("&Open", keys.CmdOrCtrl("o"), openFile),
			menu.Separator(),
			menu.Text("Quit", keys.CmdOrCtrl("q"), func(_ *menu.CallbackData) {
				runtime.Quit()
			}),
		)),
    )

    runtime.MenuSetApplicationMenu(myMenu)

```

上面的示例使用快捷方法，但是可以手动构建菜单结构。

## 菜单

菜单是菜单项的集合：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
type Menu struct {
	Items []*MenuItem
}
```

对于应用程序菜单，每个菜单项代表一个菜单，例如“编辑”。

提供了一个简单的快捷方法来构建菜单：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
func NewMenuFromItems(first *MenuItem, rest ...*MenuItem) *Menu
```

这使得代码的布局更像是菜单的布局，而无需在创建菜单项后手动添加它们。或者，您可以只创建菜单项并手动将它们添加到菜单中。

## 菜单项

菜单项表示菜单中的一个项目。

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
// MenuItem represents a menu item contained in a menu
type MenuItem struct {
	Label string
	Role Role
	Accelerator *keys.Accelerator
	Type Type
	Disabled bool
	Hidden bool
	Checked bool
	SubMenu *Menu
	Click Callback
}
```

| 字段        | 类型                          | 笔记                                        |
| ----------- | ----------------------------- | ------------------------------------------- |
| Label       | string                        | 菜单文字                                    |
| Accelerator | [\*keys.Accelerator](#加速器) | 此菜单项的键绑定                            |
| Type        | [Type](#类型)                 | 菜单项的类型                                |
| Disabled    | bool                          | 禁用菜单项                                  |
| Hidden      | bool                          | 隐藏此菜单项                                |
| Checked     | bool                          | 向菜单项设置选中 (复选框和单选类型)         |
| SubMenu     | [\*Menu](#菜单)               | 设置子菜单                                  |
| Click       | [Callback](#回调)             | 单击菜单时的回调函数                        |
| Role        | string                        | 定义此菜单项的[角色](#角色)。暂时只支持 Mac |

### 加速器

加速器（有时称为键盘快捷键）定义了按键和菜单项之间的绑定。 Wails 将加速器定义为一个组合或键 + [修饰符](#修饰符)。
它们在`"github.com/wailsapp/wails/v2/pkg/menu/keys"`包中可用。

示例:

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu/keys"
    // Defines cmd+o on Mac and ctrl-o on Window/Linux
    myShortcut := keys.CmdOrCtrl("o")
```

键是键盘上除了`+`的任何字符，它被定义为`加号`。有些键不能表示为字符，因此可以使用一组命名字符：

- `backspace`
- `tab`
- `return`
- `enter`
- `escape`
- `left`
- `right`
- `up`
- `down`
- `space`
- `delete`
- `home`
- `end`
- `page up`
- `page down`
- `f1`
- `f2`
- `f3`
- `f4`
- `f5`
- `f6`
- `f7`
- `f8`
- `f9`
- `f10`
- `f11`
- `f12`
- `f13`
- `f14`
- `f15`
- `f16`
- `f17`
- `f18`
- `f19`
- `f20`
- `f21`
- `f22`
- `f23`
- `f24`
- `f25`
- `f26`
- `f27`
- `f28`
- `f29`
- `f30`
- `f31`
- `f32`
- `f33`
- `f34`
- `f35`
- `numlock`

Wails 还支持使用与 Electron 相同的语法来解析加速器。 这对于在配置文件中存储加速器很有用。

示例:

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu/keys"
    // Defines cmd+o on Mac and ctrl-o on Window/Linux
    myShortcut, err := keys.Parse("Ctrl+Option+A")
```

#### 修饰符

以下修饰符是可以与加速键组合使用的键：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu/keys"
const (
	// CmdOrCtrlKey represents Command on Mac and Control on other platforms
	CmdOrCtrlKey Modifier = "cmdorctrl"
	// OptionOrAltKey represents Option on Mac and Alt on other platforms
	OptionOrAltKey Modifier = "optionoralt"
	// ShiftKey represents the shift key on all systems
	ShiftKey Modifier = "shift"
	// ControlKey represents the control key on all systems
	ControlKey Modifier = "ctrl"
)
```

许多快捷方法可用于使用修饰符创建加速器：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu/keys"
func CmdOrCtrl(key string) *Accelerator
func OptionOrAlt(key string) *Accelerator
func Shift(key string) *Accelerator
func Control(key string) *Accelerator
```

修饰符可以结合`keys.Combo(key string, modifier1 Modifier, modifier2 Modifier, rest ...Modifier)`使用：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu/keys"
    // Defines "Ctrl+Option+A" on Mac and "Ctrl+Alt+A" on Window/Linux
    myShortcut := keys.Combo("a", ControlKey, OptionOrAltKey)
```

### 类型

每个菜单项必须有一个类型，有 5 种类型可用：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
const (
	TextType Type = "Text"
	SeparatorType Type = "Separator"
	SubmenuType Type = "Submenu"
	CheckboxType Type = "Checkbox"
	RadioType Type = "Radio"
)
```

为方便起见，提供了快捷方法来快速创建菜单项：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
func Text(label string, accelerator *keys.Accelerator, click Callback) *MenuItem
func Separator() *MenuItem
func Radio(label string, selected bool, accelerator *keys.Accelerator, click Callback) *MenuItem
func Checkbox(label string, checked bool, accelerator *keys.Accelerator, click Callback) *MenuItem
func SubMenu(label string, menu *Menu) *MenuItem
```

关于单选菜单组的说明:单选菜单组定义为菜单中相邻的多个单选菜单项。这意味着您不需要将项目分组在一起，因为它是自动的。
然而，这也意味着您不能有两个相邻的单选菜单组-它们之间必须有一个非单选菜单项。

### 回调

每个菜单项都可能有一个回调，在单击该项时会执行该回调：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
type Callback func(*CallbackData)

type CallbackData struct {
	MenuItem    *MenuItem
}
```

给函数一个`CallbackData`结构体，它指示哪个菜单项触发了回调。这在使用可能共享回调的单选菜单组时很有用。

### 角色

:::info 角色

目前仅 Mac 支持角色。

:::

一个菜单项可能有一个角色，它本质上是一个预定义的菜单项。我们目前支持以下角色：

| 角色         | 描述                                                  |
| ------------ | ----------------------------------------------------- |
| AppMenuRole  | 标准的 Mac 应用程序菜单。可以使用`menu.AppMenu()`创建 |
| EditMenuRole | 标准的 Mac 编辑菜单。可以使用`menu.EditMenu()`创建    |
