fyne 是多数人起步的最优解,因其纯 go 实现、零 cgo 依赖、开箱即用,通过 opengl/skia 自绘 ui 实现跨平台一致性,编译为静态二进制,安装仅需 go get,布局简洁,避开了 andlabs/ui 的构建复杂性和 walk 的平台局限性。

Go 本身不带 GUI 标准库,但用它做跨平台桌面应用完全可行——关键不是“能不能”,而是“选哪个库、怎么避坑、哪些平台要特别处理”。
为什么 fyne.io/fyne/v2 是多数人起步的最优解
Fyne 是纯 Go 实现、零 cgo 依赖、开箱即用的跨平台 GUI 框架。它不调用系统原生控件,而是用 OpenGL / Skia 自绘 UI,因此 Windows/macOS/Linux 表现一致,编译后就是一个静态二进制文件,没有运行时 DLL 或 GTK 依赖。
- 安装只需
go get fyne.io/fyne/v2,无需额外 C 工具链(不像github.com/andlabs/ui必须启用 cgo 并安装 libui) -
app.New()后直接NewWindow,ShowAndRun()进入事件循环,无显式 goroutine 管理或主循环手写 - 布局靠
container.NewVBox/NewGridWithColumns组合,不需手动计算坐标,也不依赖 CSS(虽支持主题,但非必需) - 常见陷阱:误以为
widget.NewLabel支持 HTML 渲染 —— 它只渲染纯文本;富文本要用widget.RichText
github.com/andlabs/ui 在 Windows 上必须加 winmanifest
这个库是 libui 的 Go 绑定,真正调用系统原生控件(Windows 用 UWP-style Common Controls v6,macOS 用 NSView),所以外观最“像系统自带”。但它对构建环境要求苛刻,尤其 Windows 下漏掉清单文件会导致按钮/复选框显示为灰色方块、字体模糊、DPI 缩放异常。
- 必须 import
_ "github.com/andlabs/ui/winmanifest"(下划线导入触发 init 函数注入 manifest) - macOS 需要启用
CGO_ENABLED=1,且系统已装pkg-config和libui头文件(brew install libui) - Linux 用户常卡在 GTK+ 3.10+ 版本检测失败 —— 实际上 Ubuntu 22.04 默认 GTK 3.24 没问题,但某些 Alpine 镜像需手动编译 libui
-
ui.Main是阻塞调用,不能在 goroutine 里启动;所有 UI 操作必须在主线程,否则崩溃(panic: runtime error: invalid memory address)
别碰 github.com/lxn/walk 除非你只做 Windows 工具
Walk 封装 Win32 API,生成的应用在 Windows 上体验极好(支持高 DPI、触摸、Aero 效果),但 macOS/Linux 完全不可用。它的 API 设计贴近 Windows 开发者习惯(比如 walk.NewMainWindow、walk.NewButton),但代价是彻底放弃跨平台。
- 打包体积小(
- 控件事件绑定用
button.Clicked().Attach(...),不是闭包传参,容易忘记Attach导致点击无响应 - 窗口关闭逻辑必须显式调用
window.Destroy(),否则进程残留;OnClosing返回false才能取消关闭,和 Fyne 的OnClosed语义相反 - 不支持嵌套布局自动伸缩 ——
Composite容器需手动SetSize,否则子控件挤成一团
真正难的不是写第一行 widget.NewLabel,而是决定要不要为 Linux 用户适配 GTK 主题、要不要在 macOS 上支持菜单栏快捷键、要不要让 Windows 用户右键任务栏图标弹出托盘菜单——这些都不是框架自动解决的,得看具体需求权衡。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











