ImGui 基础概念

如果您是初次使用 ImGui 包,我们希望您能认真阅读此页面,以保证您具备使用此包的基本概念。而后,您才可能知道您在自己的项目中需要什么,想要什么。

总体容阅读时间约为 20 min,请酌情参考。

本页面将呈现以下内容:

带简要的标题意为介绍部分,反之意为介绍全部。



ImGui 的所有内容均组织在名为 application 的,由系统提供的窗口内。

一个 application 内可以绘制多个窗口(window)

每个窗口内可以拥有若干控件。

我们可以使用一种典型代码结构来编写可视化工具:

while !app.is_closed()
    app.prepare()
    ...
    app.render()
end

app.prepare()app.render() 间设计的布局的每个窗口(包括每个控件),都将以每一帧为单位染至应用(application)上。



Open GL 是 Dear ImGui 的后端,其方法与 Dear ImGui 无关。

在 ImGui 中保留并提供了对显示器的方法:

方法 描述
number get_monitor_count() 获取系统使用显示器数量
number get_monitor_width(number monitor_id) 获取指定显示器的宽度(像素)
number get_monitor_height(number monitor_id) 获取指定显示器的高度(像素)

显示器 id 由系统分配。

例如:win10 下,显示器编号为 1~n,则在 ImGui 中显示器 id 对应为 0~n-1

单显示器下显示器 id 为 0。



application 分为两种:

application 申明方法 描述
[application] fullscreen_application(number monitor_id, string title) 创建全屏应用并返回应用对象
[application] window_application(number width, number height, string title) 创建窗口应用并返回应用对象

创建全屏应用需手动指定显示器 id。

创建窗口应用需指定长宽,需要创建与屏幕成比例的窗口,可以配合显示器方法(获取显示器长宽)使用。

application 支持设置内部所有窗口(window)的主题风格:

设置主题方法 描述
void style_color_classic() 切换到经典主题
void style_color_light() 切换到亮色主题
void style_color_dark() 切换到暗色主题


在 Dear ImGui 中,有两类向量:

  • vec2:二维向量,常用于表示坐标或长宽
  • vec4:四维向量,常用于表示有三通道和透明度的色彩(RGBA)

注意,四维色彩的值均在0~1之间(百分比表示)

ImGui 对此保留了以上设计:

[vec2] vec2(number x, number y) 返回二维向量对象,每个分量(x、y)可访问
[vec4] vec4(number x, number y, number z, number w) 返回四维向量对象,每个分量(x、y、z、w)可访问


ImGui 会为整个应用维护一个字体栈,每绘制一次窗口,都会自动使用字体栈顶的字体。

ImGui 为字体栈提供了以下方法:

方法 描述
void push_font([font]) 将字体对象压入栈顶(使字体生效)
void pop_font() 弹出字体栈栈顶对象(删除当前字体 )
[font] get_font() 获取栈顶对象(当前字体)

ImGui 为字体提供了专用的字体包 imgui_font【待更新】 和以下方法:

[font] add_font(string path, number size) 从路径中加载字体文件,指定字体大小,并返回字体对象
[font] add_font_chinese(string path, number size) 同上,适用于中文
[font] add_font_default(number size) 加载默认字体(英文),指定字体大小,并返回字体对象
[font] add_font_extend([imgui_font] data, number size) 加载 imgui_font 中的扩展字体,指定字体大小,并返回字体对象
[font] add_font_extend_cn([imgui_font] data, number size) 同上,适用于中文

对于以上需要加载字体文件的方法,都支持常用格式的字体文件。 而对于以上需要加载字体对象(imgui_font)的方法,则需要由 imgui_font 包额外提供。

import imgui
import imgui_font
var font0 = add_font_extend_cn(imgui_font.source_han_sans,25)
var font1 = add_font_default(25)
...
while !app.is_closed
    app.prepare()
    push_font(font0)
    ... # 此处控件使用 font0 字体
    pop_font()
    push_font(font1)
    ... # 此处控件使用 font1 字体
    app.render()
end


ImGui 的提供的窗口仅在应用中生效,即:应用内窗口。

窗口是控件的载体,每个应用内可以涵有若干窗口。

一般来说,通过如下的方式来设置窗口

方法 描述
void set_window_pos([vec2] pos) 设置当前窗口位置
void set_window_size([vec2] size) 设置当前窗口大小
void begin_window(string title_and_id, boolean is_open, array flags) 开始新窗口布局
void end_window() 结束窗口布局

对于以上方法做出解释。

例如,在 app 内绘制一个 window,然后渲染:

while !app.is_closed
    app.prepare()
        begin_window("my_window##mw1", mw1_isopen, {})
            set_window_pos(vec2(0,0))
            set_window_size(vec2(get_widow_width(app),get_widow_height(app)))
            ...
        end_window()
    app.render()
end

title_and_id
参数 title_and_id 表示该窗口的标题与 id 号,该参数由标题与 id 号两个字符串分构成,中间使用“##”隔开。
一个 title_and_id 可以没有 id 号,只有 title 标题的字符串。
合法的 title_and_id 例如:“title##1”、“title##a”、“1#”;非法的 title_and_id 有“1##”。
is_open
参数 is_open 必须一个变量的引用,即:必须是一个变量,而不能是一个具体的 boolean 常量。
这是因为每个 window 需要一个变量来记录是否被关闭(点击关闭按钮事件),从而达到检测窗口是否关闭的效果。
flags
参数 flags 为创建窗口时所携带的参数。包括**无标题栏**、**自适应大小**等。



互动类控件通常使用返回boolean类型的值,来表示其状态。

如按钮(button):

...
begin_window(...)
    if button("click me!")
        # do something
    ...
end_window()

控件种类繁多,不在此一一赘述。如有需要可以参考 ImGui 控件文档。


标识符:一般用于右键菜单等,默认情况下标识符就是控件名,但有些控件无 ID 时就要特别标示

一般控件名可使用title##id的形式指定控件的标识符

方法 描述
void push_id(string title_and_id) 创建新标识符
void pop_id() 结束标识符


ImGui支持使用begin_group()end_group()一对方法标签,将若干控件组合为一个组(group),并对其实施统一的布局行为。 以下改变布局的行为,仅对组内控件生效:

方法 描述
void begin_group() 开始新组
void end_group() 结束组
void separator() 横向分割线
void same_line() 设置下一个控件为同一行
void spacing() 插入空格
void indent() 缩进
void unindent() 反缩进

另外还有树形节点,您可以理解为组(group)的树状形式:

方法 描述
boolean tree_node(string label) 创建新的树节点
void tree_pop() 结束树节点

注意:只有 tree_node()返回真时才需要调用 tree_pop()

可以粗浅理解为“当前选中的窗口或控件”。大部分I/O指令都作用于焦点控件(或窗口)上。焦点会被鼠标左键触发设置,您也可以自行设置焦点(根据逻辑)。

方法 描述
void set_scroll_here() 将滚动条滚动到当前位置
void set_keyboard_focus_here() 设置上一个控件为键盘焦点


画板提供了在窗口内绘图的系列方法。

方法 描述
void add_line([vec2] a, [vec2] b, [vec4] color, number thickness) 绘制线段
void add_rect([vec2] a, [vec2] b, [vec4] color, number rounding, number thickness) 绘制矩形线框
void add_rect_filled([vec2] a, [vec2] b, [vec4] color, number rounding) 填充矩形
void add_quad([vec2] a, [vec2] b, [vec2] c, [vec2] d, [vec4] color, number thickness) 绘制四边形线框
void add_quad_filled([vec2] a, [vec2] b, [vec2] c, [vec2] d, [vec4] color) 填充四边形
void add_triangle([vec2] a, [vec2] b, [vec2] c, [vec4] color, number thickness) 绘制三角形线框
void add_triangle_filled([vec2] a, [vec2] b, [vec2] c, [vec4] color) 填充三角形
void add_circle([vec2] centre, number radius, [vec4] color, number seg, number thickness) 画圆
void add_circle_filled([vec2] centre, number radius, [vec4] color, number seg) 填充圆
void add_text([font] font,number size, [vec2] pos, [vec4] color, string text) 绘制文字
void add_image([image] image, [vec2] a, [vec2] b) 绘制图片