資源大全
官方資源
- 原始碼+例子:ocornut/imgui: Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies (github.com)
- python繫結:pyimgui/pyimgui: Cython-based Python bindings for dear imgui (github.com)
- 除錯IMGUI自身:除錯工具 ·ocornut/imgui 維基 (github.com)
- 線上示例,可定位到程式碼:ImGui Manual (pthom.github.io)
- Getting Started · ocornut/imgui Wiki (github.com)
其它
每個控制元件都帶圖示例:ImGui 簡單使用 - 無形深空 - 部落格園 (cnblogs.com)
快速入門
使用vs開啟下載的dear imgui,demo中13個project,他們之間沒有差異,只是dx或opengl等版本不一樣,示例程式碼在imgui_demo.cpp ShowDemoWindow
右鍵選單(popups)
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");
閱讀習慣:控制元件Label右置,如何左置?
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("顯示或隱藏掛點及掛件"));
輸入框無法輸入中文
字型要支援中文,否則只能用英文輸入法,對原始碼修改
imgui.InputText
TreeNodeEx vs TreeNode
有兩種樹控制元件,建議使用新版的TreeNodeEx ,下面解釋下這兩種樹控制元件的區別
TreeNode
TreeNode
是一個較舊的函式,它顯示一個簡單的樹,沒有互動性,如下所示,
TreeNodeEx
TreeNodeEx是一個較新的函式,它透過列舉支援大量選項,ImGuiTreeNodeFlags可用來設定當前選中狀態
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
有以下方法用來佈局
- SameLine
- SetCursorX
- table或列
SameLine
// 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");
固定座標,視窗拉大座標也不改變
table
請使用新的table api,文件:新表 API (1.80 #3740 ·Ocornut/Imgui (github.com),支援功能如下:
- 邊框和奇數行/偶數行背景顏色選項,滑鼠滑過的高亮
- 隱藏特定的列,可以調整列的大小
- 排序,每個表頭都可以排序
可以看table / Advanced這個例子
按鈕無法點選(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來標識,##後的內容在顯示時被忽略
因為複雜的控制元件其實維護了狀態,比如樹節點,有開關狀態,所以在幀之間需要標識,這個控制元件呼叫就是這個控制元件
錯誤示例
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區分,如:
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)
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的子節點中新增雙擊後,無法預設選中這個節點
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的作用還需要再看看