golang基于Dear ImGui的GUI界面开发插件库cimgui-go的使用
Golang基于Dear ImGui的GUI界面开发插件库cimgui-go的使用
cimgui-go是一个为Golang生成的Dear ImGui包装器项目,它提供了多个默认的后端实现,支持macOS(arm64/x86)、Windows(x64)和多种Linux发行版。
项目状态
模块概述
包名 | 描述 |
---|---|
imgui , implot , imnodes 等 |
Dear ImGui(及其插件)的实际绑定,用于显示小部件和其他UI内容 |
examples |
展示如何使用cimgui-go的示例 |
cmd/codegen |
生成Go绑定的代码生成器 |
backend |
各种后端(glfw, sdl, ebiten等)的抽象层 |
backend/* |
具体的后端实现 |
impl |
负责imgui与后端交互的包 |
cwrappers |
Dear ImGui的C包装器 |
lib |
预编译的静态库 |
thirdparty |
第三方头文件如GLFW和SDL2 |
utils |
一些实用函数 |
支持的后端
cimgui-go实现了几个ImGui后端,都放在backend/
子包中:
- GLFW (GLFW 3.3 + OpenGL)
- SDL2 (SDL 2 + OpenGL)
- Ebitengine (
import "github.com/AllenDang/cimgui-go/backend/ebitenbackend"
)
重要提示:不同解决方案使用不同的C库可能会相互冲突。建议不要同时导入GLFW和SDL后端,这可能导致链接器崩溃。
示例代码
下面是一个使用GLFW后端的完整示例:
package main
import (
"github.com/AllenDang/cimgui-go"
"github.com/AllenDang/cimgui-go/backend/glfw"
)
func main() {
// 初始化GLFW后端
backend, err := glfw.NewBackend("Demo", 1024, 768)
if err != nil {
panic(err)
}
defer backend.Dispose()
// 初始化ImGui上下文
imgui.CreateContext(nil)
defer imgui.DestroyContext(nil)
// 设置ImGui IO
io := imgui.CurrentIO()
io.SetIniFilename("") // 禁用imgui.ini文件
// 初始化ImGui GLFW绑定
backend.SetAfterCreateContextHook(func() {
glfw.InitGLFW()
})
backend.SetBeforeDestroyContextHook(func() {
glfw.ShutdownGLFW()
})
// 主循环
for backend.PollEvents() {
// 开始新帧
backend.NewFrame()
imgui.NewFrame()
// 在这里构建UI
imgui.ShowDemoWindow(nil)
// 渲染
imgui.Render()
backend.Render(imgui.RenderedDrawData())
}
}
命名约定
- 对于函数,'Im/ImGui/ig’前缀被去除
Get
前缀也被移除(有一些例外)- 如果函数来自
imgui_internal.h
,则添加Internal
前缀
指针和切片
在C中无法区分指针和切片,我们的代码默认使用指针,但你可以通过&(slice[0])
轻松将切片转换为指针。
实用函数:
utils.SliceToPtr(slice []T) *T
- 将切片转换为指针utils.PtrToSlice(ptr *T, size int) []T
- 将指针转换为给定大小的切片(使用时需小心size参数)
回调函数
目前Go(1.24)不支持通过CGO将匿名函数传递给C。我们有一个解决方案-预生成大量全局函数和一个池。请注意限制,可能会用完预生成的池并导致崩溃。
应用程序演示
贡献指南
所有类型的贡献都欢迎!但请注意:
警告:你绝不应该手动修改自动生成的文件!违反此规则的所有Pull Request都将无法通过自动检查并且不会被合并。
当前解决方案是:
- 使用cimgui的lua生成器生成函数和结构体定义为json
- 从定义生成适当的Go代码
- 使用来自imgui的后端实现
- 使用github workflow编译cimgui、glfw和其他C依赖项为静态库
要生成Go绑定,你需要:
- 安装GNU make
- 安装Go
然后只需运行make
,或make XXX
(其中XXX
是你想要生成的包名,如make imgui
,make implot
等)。
更多关于golang基于Dear ImGui的GUI界面开发插件库cimgui-go的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang基于Dear ImGui的GUI界面开发插件库cimgui-go的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用cimgui-go进行Golang GUI开发
cimgui-go是Golang绑定Dear ImGui的库,让你可以用Go语言创建轻量级、高效的图形用户界面。下面我将介绍如何使用cimgui-go进行GUI开发。
安装cimgui-go
首先需要安装cimgui-go:
go get github.com/inkyblackness/imgui-go/v4
基本使用示例
下面是一个简单的cimgui-go示例,创建一个带有按钮和文本的窗口:
package main
import (
"github.com/inkyblackness/imgui-go/v4"
"github.com/faiface/mainthread"
"github.com/go-gl/glfw/v3.3/glfw"
)
func main() {
mainthread.Run(run)
}
func run() {
// 初始化GLFW
if err := glfw.Init(); err != nil {
panic(err)
}
defer glfw.Terminate()
// 创建窗口
window, err := glfw.CreateWindow(1280, 720, "cimgui-go示例", nil, nil)
if err != nil {
panic(err)
}
defer window.Destroy()
window.MakeContextCurrent()
glfw.SwapInterval(1)
// 创建ImGui上下文
context := imgui.CreateContext(nil)
defer context.Destroy()
// 初始化ImGui GLFW绑定
imguiGLFW := imgui.NewGLFW(window)
defer imguiGLFW.Shutdown()
// 初始化ImGui OpenGL绑定
imguiOpenGL := imgui.NewOpenGL3()
defer imguiOpenGL.Shutdown()
// 主循环
for !window.ShouldClose() {
glfw.PollEvents()
// 开始新帧
imguiOpenGL.NewFrame()
imguiGLFW.NewFrame()
imgui.NewFrame()
// 创建UI
imguiDemo()
// 渲染
imgui.Render()
imguiOpenGL.Render(imgui.RenderedDrawData())
window.SwapBuffers()
}
}
func imguiDemo() {
// 创建一个窗口
imgui.Begin("Hello, cimgui-go!")
defer imgui.End()
// 添加文本
imgui.Text("这是一个简单的ImGui示例")
// 添加按钮
if imgui.Button("点击我") {
// 按钮被点击时的处理
println("按钮被点击!")
}
// 添加滑动条
var value float32 = 0.5
imgui.SliderFloat("滑动条", &value, 0, 1)
}
常用UI组件
按钮和文本
imgui.Text("这是一段文本")
if imgui.Button("按钮") {
println("按钮被点击")
}
输入框
var text string
imgui.InputText("输入框", &text)
复选框
var checked bool
imgui.Checkbox("复选框", &checked)
单选按钮
var option int
imgui.RadioButton("选项1", &option, 0)
imgui.SameLine()
imgui.RadioButton("选项2", &option, 1)
下拉菜单
var currentItem int32
items := []string{"选项1", "选项2", "选项3"}
if imgui.BeginCombo("下拉菜单", items[currentItem]) {
for i, item := range items {
if imgui.Selectable(item) {
currentItem = int32(i)
}
}
imgui.EndCombo()
}
布局控制
水平布局
imgui.BeginGroup()
imgui.Button("按钮1")
imgui.SameLine()
imgui.Button("按钮2")
imgui.EndGroup()
子窗口
imgui.BeginChild("子窗口", imgui.Vec2{200, 100}, true)
imgui.Text("子窗口内容")
imgui.EndChild()
样式定制
你可以定制ImGui的样式:
style := imgui.CurrentStyle()
style.SetColor(imgui.StyleColorText, imgui.Vec4{1, 1, 0, 1}) // 黄色文本
style.ScaleAllSizes(1.5) // 放大所有UI元素
高级功能
绘制自定义图形
drawList := imgui.WindowDrawList()
pos := imgui.CursorScreenPos()
drawList.AddRect(
pos,
imgui.Vec2{X: pos.X + 100, Y: pos.Y + 100},
imgui.PackedColor(1, 0, 0, 1), // 红色
)
使用字体
// 加载字体
io := imgui.CurrentIO()
font := io.Fonts().AddFontFromFileTTF("arial.ttf", 18)
if font == nil {
font = io.Fonts().AddFontDefault()
}
// 使用字体
imgui.PushFont(font)
imgui.Text("使用自定义字体")
imgui.PopFont()
性能优化建议
- 尽量减少UI重建次数,只在必要时更新UI
- 使用
imgui.BeginChild()
分割复杂UI - 避免在每帧中创建大量临时字符串
- 对于静态内容,考虑缓存渲染结果
总结
cimgui-go提供了Golang绑定Dear ImGui的能力,让你可以创建高效、跨平台的GUI应用程序。虽然API与C++版本略有不同,但核心概念和功能保持一致。通过组合各种UI组件和布局控制,你可以构建复杂的用户界面。
更多高级用法和示例可以参考cimgui-go的GitHub仓库和Dear ImGui的官方文档。