本文档解释了 Dear ImGui 的上下文(Context)和 IO(Input/Output)系统,它们构成了该库状态管理和与宿主应用程序通信的核心基础。ImGui Context 是包含 ImGui 运行所需所有数据的中央对象,而 IO 系统则提供了 ImGui 与宿主应用程序之间的接口。
有关窗口和布局系统的信息,请参阅 窗口和布局系统。
上下文系统旨在将所有 Dear ImGui 状态维护在一个单独的容器对象中,这使得能够
来源:imgui.h177-201 imgui_internal.h177-184 imgui.cpp566-1200
上下文 API 简单而强大
来源:imgui.h324-330 imgui.cpp1250-1300
关键上下文函数
ImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL) - 创建一个新的上下文void DestroyContext(ImGuiContext* ctx = NULL) - 销毁一个上下文(NULL 表示当前上下文)ImGuiContext* GetCurrentContext() - 获取当前上下文void SetCurrentContext(ImGuiContext* ctx) - 设置当前上下文Dear ImGui 使用一个全局指针 GImGui 来跟踪当前上下文。每个线程通常有自己的上下文,但当切换线程时,你需要显式设置当前上下文。
来源:imgui_internal.h217-220 imgui.cpp1250-1350
IO 系统充当 Dear ImGui 与你的应用程序之间的接口。它分为两个主要结构
来源:imgui.h332-339 imgui.cpp1400-1600
ImGuiIO 结构通过 ImGui::GetIO() 访问,并作为你的应用程序和 Dear ImGui 之间的主要通信通道。
ImGuiIO 的关键组成部分
输入状态(每帧由你的应用程序更新)
显示信息
配置
输出
来源:imgui.h180-181 imgui.cpp8500-9000
自 1.87 版本以来,Dear ImGui 使用了一个基于按键/鼠标事件的 API。每帧,你的平台后端都应该调用类似以下函数:
io.AddKeyEvent(ImGuiKey key, bool down)io.AddKeyAnalogEvent(ImGuiKey key, bool down, float v)io.AddMousePosEvent(float x, float y)io.AddMouseButtonEvent(int button, bool down)io.AddMouseWheelEvent(float x, float y)这使得 ImGui 能够跨所有平台一致地处理输入。直接设置 io.KeysDown[] 和 io.MouseDown[] 的旧方法现已废弃。
ImGuiPlatformIO,通过 ImGui::GetPlatformIO() 访问,包含特定于平台的注册回调函数和函数
剪贴板函数:
Platform_GetClipboardTextFnPlatform_SetClipboardTextFn平台窗口管理(用于视口/停靠)
Platform_CreateWindowPlatform_DestroyWindowPlatform_ShowWindow附加服务:
Platform_SetImeDataFnPlatform_OpenInShellFnPlatform_LocaleDecimalPoint在大多数情况下,这些函数由平台后端(例如 imgui_impl_win32、imgui_impl_glfw)自动设置。
来源:imgui.h187-188 imgui.cpp9500-9800
ImGui 维护跨帧的状态,重置某些元素同时保留其他元素,以创建连续的用户体验。
来源:imgui.cpp1400-1500 imgui.cpp3000-3200
跨帧保留:
每帧重置:
上下文 vs IO:
Dear ImGui 支持多个上下文,这对于以下方面很有用:
使用多个上下文的示例
// In thread/module A:
ImGuiContext* ctx_a = ImGui::CreateContext();
ImGui::SetCurrentContext(ctx_a);
ImGui::GetIO().DisplaySize = ImVec2(1920, 1080);
// In thread/module B:
ImGuiContext* ctx_b = ImGui::CreateContext();
ImGui::SetCurrentContext(ctx_b);
ImGui::GetIO().DisplaySize = ImVec2(800, 600);
// Switch between contexts:
ImGui::SetCurrentContext(ctx_a);
// Use context A...
ImGui::SetCurrentContext(ctx_b);
// Use context B...
使用多个上下文时,需要注意以下几点:
来源:imgui.h324-330 imgui.cpp1250-1350
ImGui Context 和 IO 系统通过一个定义明确的接口连接到平台和渲染器后端
初始化:
// Create context
ImGui::CreateContext();
// Configure IO
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
// Initialize backends
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(device, context);
每帧更新:
// Start frame
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
// UI code
ImGui::Begin("Example Window");
ImGui::Text("Hello, world!");
ImGui::End();
// End frame and render
ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
关机:
// Cleanup
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
ImGui Context 以一种允许以下方式处理内存分配:
可以通过以下方式自定义内存分配函数:
大多数 ImGui 容器(ImVector、ImChunkStream 等)在正常使用期间设计为尽量减少分配。
ImGui Context 和 IO 系统构成了 Dear ImGui 架构的基础
它们共同使 Dear ImGui 能够保持
理解这些系统对于将 Dear ImGui 正确集成到您的应用程序中至关重要,尤其是在处理多个上下文或自定义后端实现时。
刷新此 Wiki
最后索引时间2025 年 4 月 18 日(69d572)