菜单
可以将应用程序菜单添加到 Wails 项目。 可以通过定义一个 菜单结构体 并设置 菜单选项 或者通过调用运行时方法 设置应用程序菜单 来将应用程序菜单添加到 Wails 项目。
如何创建菜单的示例:
    app := NewApp()
    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(app.ctx)
    })
    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, // reference the menu above
        Bind: []interface{}{
            app,
        },
    )
    // ...
也可以通过更新菜单结构体并调用 更新应用程序菜单 来动态更新菜单 。
上面的示例使用辅助方法,但是可以手动构建菜单结构。
菜单结构体
Menu 是 MenuItem 的集合:
type Menu struct {
    Items []*MenuItem
}
对于应用程序菜单,每个 MenuItem 代表一个菜单,例如“编辑”。
提供了一个简单的辅助方法来构建菜单:
func NewMenuFromItems(first *MenuItem, rest ...*MenuItem) *Menu
这使得代码的布局更像菜单的布局,而无需在创建菜单项后手动添加它们。 或者,您可以只创建菜单项并将它们手动添加到菜单中。
菜单项结构体
MenuItem 表示菜单中的一个项目。
// 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 | 此菜单项的键绑定 | 
| 类型 | 类型 | 菜单项的类型 | 
| Disabled | bool | 禁用菜单项 | 
| Hidden | bool | 隐藏此菜单项 | 
| Checked | bool | 添加检查项目 (复选框和单选类型) | 
| SubMenu | *Menu | 设置子菜单 | 
| Click | Callback | 单击菜单时的回调函数 | 
| Role | string | 定义此菜单项的 角色。 暂时只支持 Mac | 
快捷键
加速器(有时称为键盘快捷键)定义了按键和菜单项之间的绑定。 Wails 将加速器定义为一个组合或键 + 修饰符。 它们在 "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 相同的语法来解析加速器。 这对于将加速器存储在配置文件中很有用。
示例:
    // Defines cmd+o on Mac and ctrl-o on Window/Linux
    myShortcut, err := keys.Parse("Ctrl+Option+A")
修饰符
以下修饰符是可以与加速键结合使用的键:
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"
)
许多辅助方法可用于使用修饰符创建加速器:
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) 用以下方式组合修饰符 :
    // Defines "Ctrl+Option+A" on Mac and "Ctrl+Alt+A" on Window/Linux
    myShortcut := keys.Combo("a", ControlKey, OptionOrAltKey)
类型
每个菜单项必须有一个类型,有 5 种类型可用:
const (
    TextType Type = "Text"
    SeparatorType Type = "Separator"
    SubmenuType Type = "Submenu"
    CheckboxType Type = "Checkbox"
    RadioType Type = "Radio"
)
为方便起见,提供了帮助方法来快速创建菜单项:
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
您还可以使用“添加”助手直接在菜单上创建菜单项:
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 个彼此相邻的无线电组 - 它们之间必须有一个非无线电项目。
回调
每个菜单项都可能有一个回调,在单击该项时执行:
type Callback func(*CallbackData)
type CallbackData struct {
    MenuItem    *MenuItem
}
该函数被赋予一个 CallbackData 结构,该结构指示哪个菜单项触发了回调。 这在使用可能共享回调的单选组时很有用。
角色
目前仅 Mac 支持角色。
一个菜单项可能有一个角色,它本质上是一个预定义的菜单项。 我们目前支持以下角色:
| 角色 | 描述 | 
|---|---|
| AppMenuRole | 标准的 Mac 应用程序菜单。 可以使用 menu.AppMenu()创建 | 
| EditMenuRole | 标准的 Mac 编辑菜单。 可以使用 menu.EditMenu()创建 |