Go + Fyne GUI 开发规范与助手
按本文件的规则编写和审查 Fyne 代码。细节在 references/ 中按需读取,不要凭记忆猜 API。
0. 先定性
- Fyne 是纯 Go 自绘 UI 工具包,适合内部工具、配置器、监控面板、数据处理客户端等中小体量桌面应用。
- 不适合:重度数据可视化、复杂富交互、需要原生系统控件观感的场景。判断属于此类时先告知用户风险,不要硬写。
- 当前主线为 v2 分支(v2.8 起要求 Go 1.22+,并需要 C 编译器)。具体版本以用户工程
go.mod为准,一切 API 判断以该版本为准,禁止把 v1 或旧 v2.x 的写法混进新代码。
1. 四条硬约束(不可违反)
- 必须有事件循环。
app.New()只创建实例,界面要显示必须走到w.ShowAndRun()或a.Show()+a.Run()。缺这一步是"程序秒退、窗口不出现"的第一原因。 - UI 只能在 Fyne 自己的 goroutine 上改。 自建
go func()里调用任何 Fyne API(改控件、Refresh()、Resize()、弹窗、增删子对象)都必须包进fyne.Do(func(){...});需要确认改完再继续用fyne.DoAndWait(func(){...})。v2.6 起所有事件回调都在同一 goroutine,v2.9 起该线程模型为默认;v2.8 需按官方文档开启[Migrations] fyneDo = true。 - 禁止给控件绝对定位。 不用
Move()或硬编码坐标拼界面,改用容器加布局(container.NewVBox、NewHBox、NewBorder、NewGridWithColumns、NewCenter、layout.Spacer{})。界面必须能随窗口缩放。 - 分发用
fyne package,不用裸go build。 图标、元数据、平台包结构由 CLI 生成;资源必须编译进二进制(fyne bundle或go:embed加fyne.NewStaticResource),禁止运行时按相对路径读文件。
CLI 的正确安装路径是 go install fyne.io/tools/cmd/fyne@latest。注意:网上大量教程仍写 fyne.io/fyne/v2/cmd/fyne@latest,该旧路径已迁出主仓库,遇到要直接纠正。
2. 工作流
A. 新建 Fyne 项目
- 跑环境自检:Windows 用
scripts/check-env.ps1,macOS 或 Linux 用scripts/check-env.sh。有 FAIL 先修环境,不要先写代码。 - 以
assets/skeleton/为起点复制到用户目标目录,改掉go.mod的 module 路径与FyneApp.toml的ID、Name、Version。该骨架已体现分包、绑定、fyne.Do、工具栏与后台任务的规范写法。 - 需求换成界面:先定顶层容器(
NewBorder承载工具栏、状态栏加中心内容),再填控件,最后接数据与业务。 go mod tidy→go vet ./...→gofmt -l .必须干净 →go run ./cmd/<app>实机确认窗口正常。
B. 修改或审查既有 Fyne 工程
- 读
go.mod确认 Fyne 版本,读入口文件确认事件循环怎么起的。 - 定位用户要改的视图文件再改。改动前后各跑一次
go build ./...。 - 审查时逐条对照第 1 节硬约束和第 4 节自检清单,指出违反项并给替换写法。
C. 美化与换肤
读 references/theme-and-visual.md,按五层递进:内置主题打底 → 自定义 Theme 定品牌色/字体 → canvas 对象做局部精修 → 自定义控件改造个别外观 → 容器留白与动效收尾。硬规矩:明暗两套变体都要处理;fyne.Tappable / desktop.Hoverable 等接口必须实现,光写 OnTapped 字段不会生效;可运行参考在 assets/theme-demo/main.go。
D. 打包交付
读 references/packaging-and-env.md。桌面用 fyne package -os windows|linux|darwin -icon Icon.png,减小体积加 -release;移动端与交叉编译走 fyne-cross。打包产物要在目标平台实跑一次再交付。
3. 参考资料(按需读取,不要全读)
| 需要什么 | 读哪个 |
| --- | --- |
| 控件选型、布局容器、对话框、菜单、快捷键、偏好存储、主题、资源嵌入 | references/layout-and-widgets.md |
| 数据绑定 API 与并发、后台任务的规范写法(含代码样例) | references/binding-and-concurrency.md |
| 环境准备、FyneApp.toml、打包命令、移动端与交叉编译 | references/packaging-and-env.md |
| 界面美化、换肤、品牌色、深色模式、圆角/投影/渐变/毛玻璃/动画、自定义控件外观 | references/theme-and-visual.md |
| 编译失败、黑屏、闪退、乱码、渲染异常等报错对照 | references/troubleshooting.md |
API 签名不确定时,优先读官方文档 https://docs.fyne.io/api/v2/ 或用户本地 go.mod 指向版本的 pkg.go.dev,不要凭印象编造函数名和参数。
4. 交付前自检清单
逐条确认后再交付,任一条不满足就是返工点:
- [ ] 走到
ShowAndRun()或Run(),窗口可正常显示与关闭 - [ ] 所有 goroutine 内的 UI 更新都包在
fyne.Do或fyne.DoAndWait中 - [ ] 长耗时操作(IO、网络、扫描、导入)不在回调里同步阻塞,UI 不卡死
- [ ] 无绝对定位,窗口拉大拉小界面不破
- [ ] 数据展示走绑定或
Refresh(),无"改了变量界面不变" - [ ] 资源已 bundle 或 embed 进二进制,打包后仍读得到
- [ ]
go vet、gofmt干净,go build通过 - [ ] 图标为
.png源文件,FyneApp.toml元数据完整 - [ ] 中文界面在目标平台显示正常(默认主题字形不足时须自备字体)
- [ ] 若声明跨平台,已按目标平台分别验证,未把单平台专属代码写死
- [ ] 涉及主题/换肤时,浅色与深色两套均已实跑(
FYNE_THEME=light|dark),无可读性崩坏的配色组合 - [ ] 涉及动效时,常驻动画不超过 1–2 个,远程桌面/软渲染环境实测不掉帧或有降级方案
5. 禁止事项
- 不猜 API 名、参数、构造器;不确定就查文档或先编译验证。
- 不为绕过编译错误去降级 Fyne 版本、关掉 CGO 或删除用户已有依赖。
- 不把
time.Sleep当作界面刷新手段;轮询用ticker且更新包fyne.Do。 - 不在未确认工程版本时引入
canvas高级绘制、shader 或新驱动写法。 - 修改用户工程默认原地改,不擅自另存副本。
Scan to join WeChat group