Dear ImGui 中的小部件系统是负责创建和管理所有交互式 UI 元素的核心组件。它实现了即时模式 GUI 范式,其中小部件是在每一帧重新创建的,而不是作为持久对象存在。本文档全面概述了小部件架构、常见模式和可用的小部件类型。
有关特定小部件类别的详细信息,请参见
小部件系统是 Dear ImGui 即时模式设计的核心,在当前窗口和帧的上下文中运行。小部件不是持久对象,而是用于在每一帧创建、绘制和处理 UI 元素交互的函数。
来源: imgui_widgets.cpp142-412 imgui.h318-393
小部件在 ImGui 上下文中运行,并依赖于几个核心子系统才能正常工作。
来源: imgui.cpp78-98 imgui_internal.h178-182
Dear ImGui 小部件遵循一致的交互模型,使其易于使用和实现。
大多数小部件可以存在于以下状态
| 状态管理 | 描述 | 触发器 |
|---|---|---|
| 普通用户 | 默认显示状态 | 默认状态 |
| 悬停 | 鼠标悬停在小部件上 | 鼠标移动 |
| 激活 | 小部件正在进行交互 | 鼠标点击,键盘焦点 |
| 聚焦 | 小部件具有键盘焦点 | Tab 键导航,点击 |
| 已禁用 | 小部件显示为灰色,不响应输入 | 通过 BeginDisabled() 编程控制 |
来源: imgui_widgets.cpp132-155 imgui_internal.h187-207
每个小部件在其作用域内都需要一个唯一的 ID,以正确跟踪其状态。ID 可以从以下方式生成:
来源: imgui_internal.h362-364 imgui.cpp80-85
大多数 Dear ImGui 小部件遵循相似的模式,使其使用起来一致且可预测。
小部件函数通常遵循以下模式
bool Button(const char* label)bool Checkbox(const char* label, bool* v)bool SliderFloat(const char* label, float* v, float v_min, float v_max)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", ¤t, 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", ¤t, items, count) |
| 可选择项 | 可选择项(通常用于列表中) | Selectable("Item", selected) |
来源: imgui_widgets.cpp4500-5500 imgui_tables.cpp245-300
了解小部件的内部工作原理有助于创建自定义小部件或调试问题。
来源: imgui_widgets.cpp160-270 imgui_internal.h335-359
大多数小部件实现遵循以下通用模式
ItemSize() 预留空间ItemAdd() 添加项目(如果被裁剪则返回 false)来源: imgui_widgets.cpp414-490 imgui_internal.h200-220
当内置小部件无法满足您的需求时,您可以创建自定义小部件。以下是一些方法:
BeginGroup()/EndGroup() 将多个小部件视为一个ItemAdd()、ButtonBehavior() 和绘制列表命令来源: imgui_demo.cpp2000-2500 imgui_internal.h335-359
为了最大限度地利用 Dear ImGui 的小部件系统
IsItemHovered() && SetTooltip())提供额外信息IsItemActive()、IsItemHovered() 等检查交互BeginDisabled()/EndDisabled() 阻止用户交互来源: imgui_demo.cpp252-280 imgui.cpp35-50
小部件系统与其他 Dear ImGui 子系统交互
来源: imgui.cpp78-98 imgui_internal.h178-182
Dear ImGui 小部件系统提供了一整套具有一致 API 和行为的 UI 元素。其即时模式设计使其轻巧灵活,而广泛可用的小部件涵盖了大多数 UI 需求。理解小部件系统背后的核心模式和原则,可以有效使用内置小部件并在必要时创建自定义小部件。