菜单

控件系统

相关源文件

Dear ImGui 中的小部件系统是负责创建和管理所有交互式 UI 元素的核心组件。它实现了即时模式 GUI 范式,其中小部件是在每一帧重新创建的,而不是作为持久对象存在。本文档全面概述了小部件架构、常见模式和可用的小部件类型。

有关特定小部件类别的详细信息,请参见

小部件架构

小部件系统是 Dear ImGui 即时模式设计的核心,在当前窗口和帧的上下文中运行。小部件不是持久对象,而是用于在每一帧创建、绘制和处理 UI 元素交互的函数。

来源: imgui_widgets.cpp142-412 imgui.h318-393

与 ImGui 核心的关系

小部件在 ImGui 上下文中运行,并依赖于几个核心子系统才能正常工作。

来源: imgui.cpp78-98 imgui_internal.h178-182

小部件交互模型

Dear ImGui 小部件遵循一致的交互模型,使其易于使用和实现。

小部件状态

大多数小部件可以存在于以下状态

状态管理描述触发器
普通用户默认显示状态默认状态
悬停鼠标悬停在小部件上鼠标移动
激活小部件正在进行交互鼠标点击,键盘焦点
聚焦小部件具有键盘焦点Tab 键导航,点击
已禁用小部件显示为灰色,不响应输入通过 BeginDisabled() 编程控制

来源: imgui_widgets.cpp132-155 imgui_internal.h187-207

小部件 ID 系统

每个小部件在其作用域内都需要一个唯一的 ID,以正确跟踪其状态。ID 可以从以下方式生成:

来源: imgui_internal.h362-364 imgui.cpp80-85

常见小部件模式

大多数 Dear ImGui 小部件遵循相似的模式,使其使用起来一致且可预测。

小部件函数签名

小部件函数通常遵循以下模式

  1. 简单小部件: bool Button(const char* label)
  2. 带状态的小部件: bool Checkbox(const char* label, bool* v)
  3. 带值范围的小部件: bool SliderFloat(const char* label, float* v, float v_min, float v_max)
  4. 容器小部件: bool BeginTabBar(const char* str_id) / void EndTabBar()

来源: imgui.h350-394 imgui_widgets.cpp414-490

布局和定位

小部件根据当前光标位置和布局流自动定位

来源: imgui_widgets.cpp160-266 imgui_internal.h335-359

小部件类别

Dear ImGui 提供了各种小部件类型来构建您的界面。以下是主要类别的概述:

基本控件

这些是用于显示信息或触发简单动作的基本 UI 元素

小部件描述函数示例
文本显示文本Text("Hello, world")
按钮可点击按钮Button("Click me")
复选框切换布尔状态Checkbox("Enable", &my_bool)
单选按钮从多个选项中选择一个RadioButton("Option A", &var, 0)
项目符号项目符号点Bullet(); Text("Item")
图片显示图片Image(my_texture_id, ImVec2(w, h))
进度条显示进度ProgressBar(0.5f, ImVec2(w, h))

来源: imgui_widgets.cpp142-412 imgui_widgets.cpp414-490

输入小部件

用于输入和操作数据的小部件

小部件描述函数示例
输入文本文本输入框InputText("Name", buf, sizeof(buf))
InputInt/Float数字输入InputInt("Age", &age)
滑块带有视觉滑块的值选择SliderFloat("Scale", &scale, 0.0f, 1.0f)
拖拽整型/浮点型可拖拽值DragFloat("Speed", &speed, 0.1f)
颜色编辑颜色选择ColorEdit3("Color", color)
组合框下拉列表选择Combo("Items", &current, items, IM_ARRAYSIZE(items))

来源: imgui_widgets.cpp1500-3000 imgui_demo.cpp1200-1500

容器小部件

可以包含其他小部件或提供组织结构的小部件

小部件描述函数示例
树节点可折叠的层级节点if (TreeNode("Section")) { /* ... */ TreePop(); }
折叠标题带有折叠/展开功能的章节标题if (CollapsingHeader("Details")) { /* ... */ }
选项卡栏/选项卡项选项卡式界面if (BeginTabBar("Tabs")) { /* ... */ EndTabBar(); }
菜单/菜单项菜单系统if (BeginMenu("File")) { /* ... */ EndMenu(); }
弹出框模态或上下文弹出窗口if (BeginPopup("context")) { /* ... */ EndPopup(); }
子窗口可滚动区域if (BeginChild("child")) { /* ... */ EndChild(); }

来源: imgui_widgets.cpp3000-4500 imgui_demo.cpp1500-2000

高级控件

更复杂的小部件,用于特殊功能

小部件描述函数示例
表格带列和行的网格布局if (BeginTable("table", columns)) { /* ... */ EndTable(); }
图表简单的数据可视化PlotLines("Curve", values, count)
列表框可滚动列表选择ListBox("List", &current, items, count)
可选择项可选择项(通常用于列表中)Selectable("Item", selected)

来源: imgui_widgets.cpp4500-5500 imgui_tables.cpp245-300

小部件实现细节

了解小部件的内部工作原理有助于创建自定义小部件或调试问题。

小部件内部流程

来源: imgui_widgets.cpp160-270 imgui_internal.h335-359

常见小部件实现模式

大多数小部件实现遵循以下通用模式

  1. 为小部件生成 ID(通常来自标签)
  2. 使用 ItemSize() 预留空间
  3. 使用 ItemAdd() 添加项目(如果被裁剪则返回 false)
  4. 如果可交互,则处理输入
  5. 根据状态渲染外观
  6. 返回交互结果

来源: imgui_widgets.cpp414-490 imgui_internal.h200-220

创建自定义小部件

当内置小部件无法满足您的需求时,您可以创建自定义小部件。以下是一些方法:

  1. 组合现有小部件:最常见的方法,使用 BeginGroup()/EndGroup() 将多个小部件视为一个
  2. 低级自定义小部件:使用核心 ImGui 函数,如 ItemAdd()ButtonBehavior() 和绘制列表命令
  3. 扩展现有小部件:从类似的小部件开始并进行自定义

自定义小部件示例模式

来源: imgui_demo.cpp2000-2500 imgui_internal.h335-359

小部件使用最佳实践

为了最大限度地利用 Dear ImGui 的小部件系统

  1. 唯一标识符:确保小部件在其作用域内具有唯一的标识符
  2. 一致的布局:保持小部件宽度和间距的一致性,以实现美观的 UI
  3. 工具提示:使用工具提示(IsItemHovered() && SetTooltip())提供额外信息
  4. 小部件状态:使用 IsItemActive()IsItemHovered() 等检查交互
  5. 受控可变性:在适当的时候使用 BeginDisabled()/EndDisabled() 阻止用户交互
  6. 视觉一致性:使用一致的标签模式和小部件大小

来源: imgui_demo.cpp252-280 imgui.cpp35-50

小部件系统集成点

小部件系统与其他 Dear ImGui 子系统交互

来源: imgui.cpp78-98 imgui_internal.h178-182

结论

Dear ImGui 小部件系统提供了一整套具有一致 API 和行为的 UI 元素。其即时模式设计使其轻巧灵活,而广泛可用的小部件涵盖了大多数 UI 需求。理解小部件系统背后的核心模式和原则,可以有效使用内置小部件并在必要时创建自定义小部件。