十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Wails v3 系统托盘实战指南:用 systray-basic 示例实现托盘图标与附属窗口

Wails v3 系统托盘实战指南:用 systray-basic 示例实现托盘图标与附属窗口 Wails v3 系统托盘实战指南用 systray-basic 示例实现托盘图标与附属窗口【免费下载链接】wailsCreate beautiful applications using Go项目地址: https://gitcode.com/gh_mirrors/wa/wailsWails v3 为 Go 开发者提供了跨平台系统托盘System Tray能力可在应用退出后常驻菜单栏/通知区域。本指南以官方示例 v3/examples/systray-basic/README.md 及完整实现 main.go 为骨架结合 v3/pkg/application/systemtray.go 与 v3/pkg/application/system_tray_manager.go 的源码深入解析托盘生命周期、附属窗口Attached Window、点击切换与失焦隐藏机制让你可以基于此模板快速打造自己的常驻托盘应用。示例概览systray-basic 做了什么systray-basic 是一个演示 Wails v3 系统托盘 API 的最小可运行示例核心行为如下创建一个系统托盘systray并附带一个 Webview 窗口窗口默认隐藏左键单击托盘图标时切换显示/隐藏窗口失去焦点时自动隐藏在 Windows 上如果图标位于通知栏的弹出区域notification flyout窗口会显示在右下角靠近图标的位置。官方状态表如下平台状态MacWorking可用WindowsWorking可用Linux未标记Linux 状态留白意味着当前示例在 Linux 上的表现未被官方验证实际功能取决于平台实现见 systemtray_linux.go。从源码结构看Linux 托盘仍处于演进中使用时应以实测为准。构建并运行示例示例目录内没有独立的go.mod它依赖仓库根目录 v3/go.mod 模块。运行方式# 在 v3 模块内执行示例属于 wails/v3 主模块 go run ./examples/systray-basic运行后macOS菜单栏出现托盘图标Dock 中不显示常规应用图标因为启用了 Accessory 激活策略Windows任务栏通知区域出现图标应用主窗口不占用任务栏左键单击图标500×500 的窗口在图标附近弹出再次单击或点击窗口外部窗口隐藏。核心实现拆解整个示例逻辑集中在 main.go 的main()函数中可分为四步创建应用、创建托盘、创建附属窗口、绑定交互。第一步创建应用app : application.New(application.Options{ Name: Systray Demo, Description: A demo of the Systray API, Assets: application.AlphaAssets, Mac: application.MacOptions{ ActivationPolicy: application.ActivationPolicyAccessory, }, })要点说明Name/Description应用元信息会体现在托盘 Tooltip 与系统相关界面中Assets: application.AlphaAssets使用内置的 Alpha 测试资产作为前端资源适合快速体验无需单独准备前端目录Mac.ActivationPolicy设置为ActivationPolicyAccessory值为 1见 application_options.go。该策略专为无主窗口的后台/托盘应用设计使应用不出现在 Dock 中配合菜单栏托盘图标构成典型 macOS 工具型应用形态。第二步创建系统托盘systemTray : app.SystemTray.New()SystemTray是 Wails v3 顶层管理器App.SystemTray暴露的能力。看 system_tray_manager.go 的实现New()会生成自增 ID将托盘注册到app.systemTrays映射中并通过runOrDeferToAppRun保证无论调用时机如何托盘都会在应用运行阶段完成平台初始化。在 systemtray.go 的构造函数中新托盘默认携带attachedWindow: WindowAttachConfig{ Window: nil, Offset: 0, Debounce: 200 * time.Millisecond, }也就是说Debounce默认 200ms用于 Windows 上抑制隐藏后立刻又显示的抖动。第三步创建附属窗口Attached Windowwindow : app.Window.NewWithOptions(application.WebviewWindowOptions{ Width: 500, Height: 500, Name: Systray Demo Window, Frameless: true, AlwaysOnTop: true, Hidden: true, DisableResize: true, HideOnEscape: true, HideOnFocusLost: true, Windows: application.WindowsWindow{ HiddenOnTaskbar: true, }, KeyBindings: map[string]func(window application.Window){ F12: func(window application.Window) { systemTray.OpenMenu() }, }, })各选项的用途均可在 webview_window_options.go 找到定义选项作用Frameless: true无边框窗口贴合托盘弹窗的轻量观感AlwaysOnTop: true置顶保证弹出时不被其他窗口遮挡Hidden: true初始隐藏等待托盘触发DisableResize: true禁止拖拽改变大小HideOnEscape: true按 Esc 隐藏窗口HideOnFocusLost: true失焦自动隐藏实现点击外部即关闭Windows.HiddenOnTaskbar: trueWindows 下隐藏任务栏条目KeyBindings注册全局按键 F12触发systemTray.OpenMenu()两个隐藏选项值得展开HideOnFocusLost源码注释明确指出webview_window_options.go它对弹出/临时窗口如托盘附属窗口非常有用。但在Linux 的 focus-follows-mouse 窗口管理器如 Hyprland、Sway、i3上会被自动禁用因为鼠标一移开窗口就隐藏体验反而变差实现见 webview_window_linux.go 的detectFocusFollowsMouse逻辑。HideOnEscape同样适合弹出式窗口用户按 Esc 即可快速收拢。第四步绑定关闭事件与交互window.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) { window.Hide() e.Cancel() })这里拦截了窗口关闭事件将关闭转译为隐藏并调用e.Cancel()取消真正的销毁。对托盘应用这是关键设计——用户点击窗口关闭按钮后应用不会退出托盘继续常驻。macOS 下设置模板图标Template Iconif runtime.GOOS darwin { systemTray.SetTemplateIcon(icons.SystrayMacTemplate) }icons.SystrayMacTemplate由 v3/pkg/icons/icons.go 通过//go:embed DefaultMacTemplateIcon.png内嵌。模板图标是 macOS 的特殊机制图标自带透明通道系统根据菜单栏的明暗模式自动渲染为黑白样式避免出现深色模式下图标看不清的问题。第五步将窗口附着到托盘systemTray.AttachWindow(window).WindowOffset(5) err : app.Run() if err ! nil { log.Fatal(err) }AttachWindow把窗口绑到托盘图标上systemtray.goAttachWindow(window)记录关联窗口图标被点击时自动切换窗口显隐WindowOffset(5)设置托盘图标与窗口之间的像素间距为 5px可选链式调用WindowDebounce(d)调整 Windows 点击防抖间隔。点击交互背后的智能默认值示例代码并未显式编写单击切换窗口的逻辑——它来自applySmartDefaultssystemtray.gofunc (s *SystemTray) applySmartDefaults() { hasWindow : s.attachedWindow.Window ! nil hasMenu : s.menu ! nil if s.clickHandler nil hasWindow { s.clickHandler s.ToggleWindow } if s.rightClickHandler nil hasMenu { s.rightClickHandler s.ShowMenu } }规则若关联了窗口且未设置单击回调 →左键单击切换窗口显隐若设置了菜单且未设置右键回调 →右键单击弹出菜单。因此只要AttachWindow了窗口即使不写任何OnClick示例行为单击切换也自然成立。ToggleWindow的实现systemtray.go会先读取窗口初始可见性再调用PositionWindow将窗口定位到图标附近后Show().Focus()。如果需要自定义行为可直接覆盖回调systemTray.OnClick(func() { /* 自定义单击逻辑 */ }) systemTray.OnRightClick(func() { /* 自定义右键逻辑 */ }) systemTray.OnDoubleClick(func() { /* 双击 */ }) systemTray.OnMouseEnter(func() { /* 鼠标进入 */ }) systemTray.OnMouseLeave(func() { /* 鼠标离开 */ })常用 API 速查以下方法均返回*SystemTray支持链式调用定义见 systemtray.go方法作用SetIcon(icon []byte)设置普通图标SetTemplateIcon(icon []byte)设置 macOS 模板图标自适应明暗SetDarkModeIcon(icon []byte)设置深色模式图标SetLabel(label string)设置托盘文本标签SetTooltip(tooltip string)设置悬停提示SetMenu(menu *Menu)关联弹出菜单SetIconPosition(pos IconPosition)设置图标与标签的相对位置macOSAttachWindow(window)/WindowOffset(n)/WindowDebounce(d)附着窗口及微调OnClick / OnRightClick / OnDoubleClick / ...注册交互回调Show() / Hide() / Destroy()显隐托盘、销毁托盘OpenMenu()要求必须先SetMenu否则直接返回systemtray.go。进阶给托盘加一个右键菜单示例只演示了单击切换托盘应用最常见的形态还包含右键菜单。参考applySmartDefaults的规则只需把菜单与托盘关联即可menu : app.NewMenu() menu.Add(显示窗口).OnClick(func(ctx *application.Context) { systemTray.ShowWindow() }) menu.Add(隐藏窗口).OnClick(func(ctx *application.Context) { systemTray.HideWindow() }) menu.AddSeparator() menu.Add(退出).OnClick(func(ctx *application.Context) { app.Quit() }) systemTray.SetMenu(menu)ShowWindow()/HideWindow()是托盘对附属窗口的显隐快捷入口systemtray.goapp.Quit()结束事件循环。平台差异与注意事项macOS务必使用ActivationPolicyAccessory 模板图标否则应用会占据 Dock 且图标在深色菜单栏下不可见。WindowsHiddenOnTaskbar让窗口不占用任务栏Debounce默认 200ms避免单击托盘图标时窗口闪一下又消失图标在通知区域弹出层时窗口会出现在右下角。LinuxREADME 未标注状态且HideOnFocusLost在 focus-follows-mouse 的 WM 下会被自动禁用见 webview_window_linux.go不同桌面环境的托盘实现差异较大建议在目标发行版上实测。关闭即隐藏通过WindowClosing钩子 e.Cancel()保证关闭窗口不退出进程这是托盘应用存活的关键。总结systray-basic用约 60 行代码串起了 Wails v3 托盘应用的全部核心链路SystemTrayManager.New()创建托盘 →AttachWindow 智能默认值实现单击切换 → 窗口选项配合实现失焦/ Esc 隐藏 →WindowClosing钩子阻止退出。基于这个模板替换图标资源与前端 Assets、增加右键菜单与自定义事件即可快速扩展出自己的常驻托盘工具。【免费下载链接】wailsCreate beautiful applications using Go项目地址: https://gitcode.com/gh_mirrors/wa/wails创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表