应选 gotk3/v3,因其基于 GTK 3.22+、支持现代构建流程、事件绑定更符合 Go 习惯,而 mattn/go-gtk 已多年未更新、易 panic 且不兼容新版 GTK 运行时。
go-gtk 与 gotk3 到底该选哪个
Debian/Ubuntu 下开发 GTK 桌面应用,
和
是两个主流绑定,但它们行为差异明显,不能混用。当前(2026 年)稳定可用的是
,它基于 GTK 3.22+,支持现代构建流程,且自带
链接逻辑;而
已多年未更新,其
事件模型容易引发 panic,且不兼容较新 GTK 运行时。
如果你看到示例里用了
并调用
,基本可以判定是过时写法——它要求 handler 必须接收
,否则运行时报
。
新项目请直接用
确保系统已装
(Debian/Ubuntu),不是
的事件连接更符合 Go 习惯:直接传函数,无需封装上下文
Debian 下编译失败常见报错及修复
运行
报
或
,本质是环境链路断了。
关键检查点:
立即学习
“
go语言免费学习笔记(深入)
”;
确认已执行
(缺
会导致头文件路径找不到)
不要跳过
:Go 默认在交叉编译时关 cgo,GTK 必须启用,建议显式加到命令前:
若提示
,说明 pkg-config 没返回正确链接参数,可临时验证:
应输出类似
gotk3 窗口初始化与事件绑定写法
的 API 更简洁,窗口生命周期和信号处理不再依赖全局
循环管理,而是靠对象方法驱动。
一个带按钮点击响应的最小可运行示例:
注意几个硬性细节:
必须在
前注册,否则关闭窗口不触发退出
所有 widget 创建后必须显式
或
到容器,GTK 不会自动挂载
是阻塞调用,必须放在最后;若想非阻塞,需另起 goroutine,但需同步控制
剪贴板、菜单、托盘等进阶功能依赖哪些包
基础窗口只是起点。真正做桌面工具,常需要剪贴板读写、系统托盘图标、原生菜单栏等——这些功能在
中分散在不同子模块,且需额外链接系统库。
例如剪贴板操作:
导入
调用
(不是
)
写入:
;读取:
系统托盘图标(status icon):
需导入
和
使用
(注意:GTK 3.14+ 已弃用,Debian 12+ 默认不可用;如需托盘,建议降级到 GTK 3.10 或改用
绑定)
真正容易被忽略的一点:GTK 的“主题适配”和“HiDPI 支持”不靠代码控制,而依赖系统环境变量。启动前加
才能在高分屏正常显示,这个必须写进启动脚本,不能只靠 Go 代码设置。
gotk3mattn/go-gtkgotk3/v3cgomattn/go-gtkglib.CallbackContextgithub.com/mattn/go-gtk/gtkConnect("clicked", handler, data)*glib.CallbackContextpanic: reflect: Call using *glib.CallbackContext as type ...go get github.com/gotk3/gotk3/v3/gtklibgtk-3-devlibgtk2.0-devgotk3go run main.goundefined: gtk.Initcgo: C compiler not foundsudo apt install libgtk-3-dev build-essential pkg-configpkg-configCGO_ENABLED=1CGO_ENABLED=1 go run main.gocannot find -lgtk-3pkg-config --libs gtk+-3.0-lgtk-3 -lgdk-3 ...gotk3/v3gtk.Main()package main
import (
"log"
"github.com/gotk3/gotk3/v3/gtk"
)
func main() {
gtk.Init(nil)
win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
if err != nil {
log.Fatal(err)
}
win.SetTitle("gotk3 示例")
win.SetDefaultSize(400, 300)
btn, _ := gtk.ButtonNewWithLabel("点我")
btn.Connect("clicked", func() {
log.Println("按钮被点击了")
})
win.Add(btn)
win.Connect("destroy", func() {
gtk.MainQuit()
})
win.ShowAll()
gtk.Main()
}
win.Connect("destroy", ...)win.ShowAll()Add()PackStart()gtk.Main()gotk3github.com/gotk3/gotk3/v3/gdkclipboard := gdk.ClipboardGetDefault()gtk.ClipboardGet(...)clipboard.SetText("hello")text, _ := clipboard.GetText()github.com/gotk3/gotk3/v3/gtkgithub.com/gotk3/gotk3/v3/gdkgtk.StatusIconNew()libappindicator3GDK_SCALE=2 GDK_DPI_SCALE=1