---
sidebar_position: 4
---

# 菜单

可以将应用程序菜单添加到 Wails 项目。 可以通过定义一个 [菜单结构体](#菜单结构体) 并设置 [`菜单选项`](../reference/options#菜单) 或者通过调用运行时方法 [设置应用程序菜单](../reference/runtime/menu#设置应用程序菜单) 来将应用程序菜单添加到 Wails 项目。

如何创建菜单的示例：

```go
    AppMenu := menu.NewMenu()
    FileMenu := AppMenu.AddSubmenu("File")
    FileMenu.AddText("&Open", keys.CmdOrCtrl("o"), openFile)
    FileMenu.AddSeparator()
    FileMenu.AddText("Quit", keys.CmdOrCtrl("q"), func(_ *menu.CallbackData) {
        runtime.Quit()
    })

    if runtime.GOOS == "darwin" {
    AppMenu.Append(menu.EditMenu())  // on macos platform, we should append EditMenu to enable Cmd+C,Cmd+V,Cmd+Z... shortcut
    }

    err := wails.Run(&options.App{
        Title:             "Menus Demo",
        Width:             800,
        Height:            600,
        Menu:              AppMenu,
        Bind: []interface{}{
            app,
        },
    )
    // ...
```

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

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

## 菜单结构体

Menu 是 MenuItem 的集合：

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

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

提供了一个简单的辅助方法来构建菜单：

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

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

## 菜单项结构体

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

```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](#accelerator) | 此菜单项的键绑定                     |
| 类型          | [类型](#type)                          | 菜单项的类型                       |
| Disabled    | bool                                 | 禁用菜单项                        |
| Hidden      | bool                                 | 隐藏此菜单项                       |
| Checked     | bool                                 | 添加检查项目 (复选框和单选类型)            |
| SubMenu     | [\*Menu](#menu)                    | 设置子菜单                        |
| Click       | [Callback](#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` | `f1`  |   `f16`   |   `f31`   |
|    `tab`    | `f2`  |   `f17`   |   `f32`   |
|  `return`   | `f3`  |   `f18`   |   `f33`   |
|   `enter`   | `f4`  |   `f19`   |   `f34`   |
|  `escape`   | `f5`  |   `f20`   |   `f35`   |
|   `left`    | `f6`  |   `f21`   | `numlock` |
|   `right`   | `f7`  |   `f22`   |           |
|    `up`     | `f8`  |   `f23`   |           |
|   `down`    | `f9`  |   `f24`   |           |
|   `space`   | `f10` |   `f25`   |           |
|  `delete`   | `f11` |   `f36`   |           |
|   `home`    | `f12` |   `f37`   |           |
|    `end`    | `f13` |   `f38`   |           |
|  `page up`  | `f14` | `page up` |           |
| `page down` | `f15` |   `f30`   |           |

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) *Menu
```

您还可以使用“添加”助手直接在菜单上创建菜单项：

```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
func (m *Menu) AddText(label string, accelerator *keys.Accelerator, click Callback) *MenuItem
func (m *Menu) AddSeparator() *MenuItem
func (m *Menu) AddRadio(label string, selected bool, accelerator *keys.Accelerator, click Callback) *MenuItem
func (m *Menu) AddCheckbox(label string, checked bool, accelerator *keys.Accelerator, click Callback) *MenuItem
func (m *Menu) AddSubMenu(label string, menu *Menu) *MenuI
```

关于单选组的说明：单选组被定义为在菜单中彼此相邻的多个单选菜单项。 这意味着您不需要将项目组合在一起，因为它是自动的。 但是，这也意味着您不能有 2 个彼此相邻的无线电组 - 它们之间必须有一个非无线电项目。

### 回调

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

```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()` 创建  |
