You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go Fyne系统托盘菜单中点击后切换按钮文本与动作

解决Fyne系统托盘菜单动态更新问题

在macOS Big Sur 11.5.1(20G80)环境下使用Fyne v2.3.3开发Go程序时,实现系统托盘菜单后,点击"start"选项想将其文本改为"stop"并切换对应动作逻辑,但直接修改MenuItem的Label和Action属性后,系统托盘菜单无法自动刷新。这是因为Fyne的系统托盘菜单不会监听MenuItem的属性变化,必须重新调用SetSystemTrayMenu才能更新菜单显示。

解决方案

核心思路:

  • 维护状态变量记录当前运行状态
  • 在菜单动作中根据状态切换执行逻辑与菜单文本
  • 重新调用SetSystemTrayMenu刷新系统托盘菜单

修改后的代码

package main

import (
	"fmt"
	"sync/atomic"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/widget"
)

var (
	menu1    *fyne.MenuItem
	isRunning atomic.Bool // 原子变量保证并发安全
)

func main() {
	a := app.New()
	w := a.NewWindow("SysTray")

	if desk, ok := a.(desktop.App); ok {
		// 统一动作逻辑,根据状态切换行为
		toggleAction := func() {
			if isRunning.Load() {
				fmt.Println("stopped")
				isRunning.Store(false)
				menu1.Label = "start"
			} else {
				fmt.Println("started")
				isRunning.Store(true)
				menu1.Label = "stop"
			}
			// 重新设置菜单以刷新系统托盘显示
			m := fyne.NewMenu("MyApp", menu1, menu2, menu3)
			desk.SetSystemTrayMenu(m)
		}

		menu1 = fyne.NewMenuItem("start", toggleAction)

		menu2 := fyne.NewMenuItem("menu1", nil)
		menu2.ChildMenu = fyne.NewMenu("",
			fyne.NewMenuItem("submenu1", func() {
				fmt.Println("submenu1")
			}),
			fyne.NewMenuItem("submenu2", func() {
				fmt.Println("submenu2")
			}),
		)

		menu3 := fyne.NewMenuItem("show2", func() {
			fmt.Println("menu2")
		})

		m := fyne.NewMenu("MyApp", menu1, menu2, menu3)
		desk.SetSystemTrayMenu(m)
	}

	w.SetContent(widget.NewLabel("Fyne System Tray"))
	w.SetCloseIntercept(func() {
		w.Hide()
	})
	w.ShowAndRun()
}

关键说明

  1. 使用atomic.Bool作为状态变量,避免并发场景下的竞态问题
  2. 将菜单动作统一为toggleAction,内部根据isRunning状态切换执行逻辑与菜单文本
  3. 修改菜单文本后必须重新创建菜单并调用SetSystemTrayMenu,触发Fyne更新系统托盘的菜单显示

你的go.mod文件(无需修改)

module go-GUI

go 1.19

require fyne.io/fyne/v2 v2.3.3

require (
	fyne.io/systray v1.10.1-0.20230312215936-7f71b037e260 // indirect
	github.com/benoitkugler/textlayout v0.3.0 // indirect
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/fredbi/uri v0.1.0 // indirect
	github.com/fsnotify/fsnotify v1.5.4 // indirect
	github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
	github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect
	github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
	github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect
	github.com/go-text/typesetting v0.0.0-20221212183139-1eb938670a1f // indirect
	github.com/godbus/dbus/v5 v5.1.0 // indirect
	github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c // indirect
	github.com/gopherjs/gopherjs v1.17.2 // indirect
	github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/srwiley/oksvg v0.0.0-20220731023508-a61f04f16b76 // indirect
	github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect
	github.com/stretchr/testify v1.8.0 // indirect
	github.com/tevino/abool v1.2.0 // indirect
	github.com/yuin/goldmark v1.4.13 // indirect
	golang.org/x/image v0.0.0-20220601225756-64ec528b34cd // indirect
	golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect
	golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
	golang.org/x/text v0.6.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
	honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
)

内容的提问来源于stack exchange,提问作者Willis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:05:41