前言:
目前各位老铁们对“win10托盘图标”大约比较珍视,咱们都想要剖析一些“win10托盘图标”的相关文章。那么小编也在网上收集了一些关于“win10托盘图标””的相关知识,希望大家能喜欢,看官们快快来了解一下吧!之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的web server网页完成gui相关功能。顿时感觉,嗯,是个曲线绕开类似electron等框架的方法。
这种方式的好处是,可以把擅长写web服务的应用桌面化,当需要gui的时候,直接托盘菜单启动浏览器,完成相关功能后,直接关闭浏览器省内存。
我的gost-ui-3程序用electron编写,内部集成浏览器,安装包60-~85M,启动后内存占用超过100M,所以后面考虑节省资源的方式,可以使用托盘图标+默认浏览器的方式解决。
当然如果对 cgo 敏感的话,就不能用了,三个平台都依赖 cgo
1. golang 托盘图标的使用
因为最近常用的是windows,家里的mac已经吃灰很久了。所以暂时默认适配的是windows环境。理论上mac和linux上也是可以适配的。
最核心的是应用了 github.com/getlantern/systray 这个库。
一个最简单的示例如下:
注意提前准备好相应的图标文件
package mainimport ( _ "embed" "fmt" "github.com/getlantern/systray")// embed 指令直接读取icon文件并在编译时嵌入程序中////go:embed icon.icovar iconWin []byte// 托盘菜单描述,自定义,为了方便定义和事件管理type Menu struct { Title string Tips string Icon []byte OnClick func(m *systray.MenuItem)}// 添加菜单func AddMenu(menu *Menu) *systray.MenuItem { m := systray.AddMenuItem(menu.Title, menu.Tips) if len(menu.Icon) > 0 { m.SetIcon(menu.Icon) } go func() { for range m.ClickedCh { menu.OnClick(m) } }() return m}// 添加checkbox菜单func AddCheckboxMenu(menu *Menu, checked bool) *systray.MenuItem { m := systray.AddMenuItemCheckbox(menu.Title, menu.Tips, checked) if len(menu.Icon) > 0 { m.SetIcon(menu.Icon) } go func() { for range m.ClickedCh { menu.OnClick(m) } }() return m}func main() { systray.Run(onReady, onExit)}func onReady() { systray.SetIcon(iconWin) systray.SetTitle("托盘图标示例") systray.SetTooltip("托盘图标示例提示") // 选择框和动态菜单综合示例 AddCheckboxMenu(&Menu{ Title: "启动", OnClick: func(m *systray.MenuItem) { if m.Checked() { m.SetTitle("启动") m.Uncheck() } else { m.SetTitle("停止") m.Check() } }, }, false) // 添加退出菜单 AddMenu(&Menu{ Title: "退出", Tips: "退出程序", OnClick: func(m *systray.MenuItem) { systray.Quit() }, })}func onExit() { fmt.Printf("退出喽")}
同时看到一些可能在应用中需要用到的api方法如下
// 设置主托盘图标, 比如一个服务分别在启动状态和关闭状态使用不同的图标systray.SetTemplateIcon(_icon, _icon)// 菜单可以显示和隐藏systray.MenuItem.Show(); systray.MenuItem.Hide()// 菜单可禁止和启用systray.MenuItem.Disable(); systray.MenuItem.Enable()// 添加一组菜单的方式func AddMenuGroup(title string, sub []*Menu) { boot := systray.AddMenuItem(title, "") for _, v := range sub { mi := boot.AddSubMenuItem(v.Title, v.Title) _v := v go func() { for { select { case <-mi.ClickedCh: _v.OnClick(mi) } } }() }}2. 用 golang 打开默认浏览器
打开默认浏览器其实就是执行对应平台的系统命令。
结合我的托盘示例,一个完整的例子程序如下。主要看Open(uri string)方法。
//go:generate goversioninfopackage mainimport ( _ "embed" "fmt" "os/exec" "runtime" "github.com/getlantern/systray")//go:embed icon/icon.pngvar icon []byte//go:embed icon/icon_off.pngvar iconOff []byte//go:embed icon/icon.icovar iconWin []byte//go:embed icon/icon_off.icovar iconOffWin []byte//go:embed icon/logo.pngvar logo []byte// 不同平台打开浏览器对应的命令var commands = map[string]string{ "windows": "cmd", "darwin": "open", "linux": "xdg-open",}// 托盘菜单自定义数据结构type Menu struct { Title string Tips string Icon []byte OnClick func(m *systray.MenuItem)}func main() { systray.Run(onReady, onExit)}// 执行打开默认浏览器并访问指定uri的命令func Open(uri string) error { run, ok := commands[runtime.GOOS] if !ok { return fmt.Errorf("don't know how to open things on %s platform", runtime.GOOS) } var cmd *exec.Cmd if runtime.GOOS == "windows" { cmd = exec.Command(run, `/c`, `start`, uri) // 无console调用 cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} } else { // linux和mac下暂未测试 cmd = exec.Command(run, uri) } return cmd.Start()}// 添加一个常规菜单func AddMenu(menu *Menu) *systray.MenuItem { m := systray.AddMenuItem(menu.Title, menu.Tips) if len(menu.Icon) > 0 { m.SetIcon(menu.Icon) } go func() { for range m.ClickedCh { menu.OnClick(m) } }() return m}// 托盘启动时func onReady() { systray.SetIcon(iconWin) systray.SetTitle("托盘图标示例") systray.SetTooltip("托盘图标示例提示") // 打开一个浏览器网址 AddMenu(&Menu{ Title: "我的博客", Tips: "blog.wavesxa.com", OnClick: func(m *systray.MenuItem) { Open(";) }, }) // 退出菜单 AddMenu(&Menu{ Title: "退出", Tips: "退出程序", OnClick: func(m *systray.MenuItem) { systray.Quit() }, })}// 托盘退出时func onExit() { fmt.Printf("退出喽")}
标签: #win10托盘图标 #linux系统打开浏览器的指令