IMGUI快速入门

本文为作者原创,转载请注明出处:https://www.cnblogs.com/zhaoqingqing/p/18314971



资源大全#

官方资源

  1. 源码+例子:ocornut/imgui: Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies (github.com)
  2. python绑定:pyimgui/pyimgui: Cython-based Python bindings for dear imgui (github.com)
  3. 调试IMGUI自身:调试工具 ·ocornut/imgui 维基 (github.com)
  4. 在线示例,可定位到代码:ImGui Manual (pthom.github.io)
  5. Getting Started · ocornut/imgui Wiki (github.com)

其它

每个控件都带图示例:ImGui 简单使用 - 无形深空 - 博客园 (cnblogs.com)

快速入门#

使用vs打开下载的dear imgui,demo中13个project,他们之间没有差异,只是dx或opengl等版本不一样,示例代码在imgui_demo.cpp ShowDemoWindow

右键菜单(popups)#

Copy
if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id { selected = n; ImGui::Text("This a popup for \"%s\"!", names[n]); if (ImGui::Button("Close")) ImGui::CloseCurrentPopup(); ImGui::EndPopup(); } ImGui::SetItemTooltip("Right-click to open popup");

image-20240602161724930

阅读习惯:控件Label右置,如何左置?#

image-20240602210226755

Copy
pyimgui.begin("test window") # default label pyimgui.input_int("default label", 0) # left label pyimgui.text("left label") pyimgui.same_line() pyimgui.input_int("##left label item", 0) pyimgui.end()

中文处理#

中文乱码#

中文乱码:TO_UTF8_CSTR("显示或隐藏挂点及挂件"));

输入框无法输入中文#

字体要支持中文,否则只能用英文输入法,对源码修改

Copy
imgui.InputText

TreeNodeEx vs TreeNode#

有两种树控件,建议使用新版的TreeNodeEx ,下面解释下这两种树控件的区别

TreeNode#

TreeNode是一个较旧的函数,它显示一个简单的树,没有交互性,如下所示,

img

TreeNodeEx#

TreeNodeEx是一个较新的函数,它通过枚举支持大量选项,ImGuiTreeNodeFlags可用来设置当前选中状态

img

Copy
ImGuiTreeNodeFlags flag = ImGuiTreeNodeFlags_DefaultOpen;//树默认是打开的 if (HAS_CHILDREN) { flags |= ImGuiTreeNodeFlags_Leaf;//没有子节点的就不显示箭头 } flags |= ImGuiTreeNodeFlags_OpenOnArrow;//选择非叶节点不会切换选中状态 if (IS_SELECTED) { flags |= ImGuiTreeNodeFlags_Selected; //高亮选中当前节点 } if (ImGui::TreeNodeEx("root", flag)) //这里返回的bool是树节点是否处于打开状态,而不是点击状态 { // Call ImGui::TreeNodeEx() recursively to populate each level of children if (ImGui::IsItemClicked()) { // 当节点被点击时触发事件 } ImGui::TreePop(); // 在结尾处必须要的 }

资料:ImGui 树节点 •TreeNode与TreeNodeEx

布局Layout#

有以下方法用来布局

  1. SameLine
  2. SetCursorX
  3. table或列

SameLine#

Copy
// Aligned to arbitrary position. Easy/cheap column. IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (with offset)"); ImGui::Text("Aligned"); ImGui::SameLine(150); ImGui::Text("x=150"); ImGui::SameLine(300); ImGui::Text("x=300"); ImGui::Text("Aligned"); ImGui::SameLine(150); ImGui::SmallButton("x=150"); ImGui::SameLine(300); ImGui::SmallButton("x=300");

image-20240603112503343

固定坐标,窗口拉大坐标也不改变

table#

请使用新的table api,文档:新表 API (1.80 #3740 ·Ocornut/Imgui (github.com),支持功能如下:

  • 边框和奇数行/偶数行背景颜色选项,鼠标滑过的高亮
  • 隐藏特定的列,可以调整列的大小
  • 排序,每个表头都可以排序

可以看table / Advanced这个例子

image-20240603142730964

按钮无法点击(ID冲突)#

https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-why-is-my-widget-not-reacting-when-i-click-on-it

ImGui隐式维护ID,控件树中的控件路径被hash来标识一个控件

每个控件的接口一般都有label,是该控件的ID,ID可以是字符串(label参数),索引,或者指针

所以传空串就会导致无法交互,解决办法是用##XXX来标识,##后的内容在显示时被忽略

因为复杂的控件其实维护了状态,比如树节点,有开关状态,所以在帧之间需要标识,这个控件调用就是这个控件

错误示例#

Copy
pyimgui.begin("test window") # ID conflict if pyimgui.button("button"): # ID = hash of ("test window", "button") IINFO("button1") if pyimgui.button("button"): # ID = hash of ("test window", "button") IINFO("button2") pyimgui.end()

这个示例中,两个button的Label(ID)都叫button,因为这个Label也是ID,相同ID冲突可能导致其中一个button无法响应点击事件或同时响应事件。

解决办法#

Label中添加"##",##后的内容不会显示在面板上,可以在Label后添加"##ID"内容来做ID区分,如:

Copy
if pyimgui.button("button##foo1"): # ID = hash of ("test window", "button##foo1") IINFO("button1") if pyimgui.button("button##foo2"): # ID = hash of ("test window", "button##foo2") IINFO("button2")

##和####

Label中,"##ID"后的内容不会显示在面板上

您可能需要使用“###”运算符构建一个字符串,以保留带有变量标签的常量 ID)

Copy
static char name[32] = "Label1"; char buf[64]; sprintf(buf, "Button: %s###Button", name); / ### operator override ID ignoring the preceding label ImGui::Button(buf); //显示的是Button:Label1

双击事件#

但是碰到个问题,在TreeNodeEx的子节点中添加双击后,无法默认选中这个节点

Copy
is_selected = False def test(): opened = imgui.TreeNodeEx(name, flags=flags) if imgui.Selectable(name,is_selected,imgui.ImGuiSelectableFlags_AllowDoubleClick): if imgui.IsMouseDoubleClicked() and getattr(entity, 'model', None): #双击显示与隐藏 entity.model.visible = not entity.model.visible

FAQ#

itempick的作用还需要再看看

作者:赵青青   一名在【网易游戏】做游戏开发的程序员,擅长Unity3D,游戏开发,.NET等领域。
本文版权归作者和博客园共有,欢迎转载,转载之后请务必在文章明显位置标出原文链接和作者,谢谢。
如果本文对您有帮助,请点击【推荐】您的赞赏将鼓励我继续创作!想跟我一起进步么?那就【关注】我吧。
posted @   赵青青  阅读(1630)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签
历史上的今天:
2014-07-21 Unity Mono
CONTENTS
点击右上角即可分享
微信分享提示