【Dear Imgui】组件的使用之Text

1、Text的使用

int idHello = 0;
ImGui::Text("idHello = %d", idHello);

Tip::Text使用的参数和C语言的printf里面的参数格式一致,里面写什么,显示的就是什么

2、Text显示有颜色的字体:

ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "idHello = %d", idHello);

3、使Text支持中文字符输入输出

当我们不设置自己的字符集的时候,默认是不能显示汉字的,如果不设置自己的字符集,直接显示汉字,那么就只会显示:“?”

此时相当于我们使用了接口:

io.Fonts->AddFontDefault();

所以当我们使用汉字显示的时候,就需要设置自己的字符集:从网上下载包含汉字的.ttf文件,然后通过接口进行设置

ImGuiIO& io = ImGui::GetIO(); (void)io;
ImFont* font = io.Fonts->AddFontFromFileTTF("AaDouBanErTi-2.ttf", 15.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());

这里面最后一个参数是设置加载的多少,当前用的是加载所有汉字,还有就会可以加载常用的汉字,但是可能会比较少,两个接口如下:

io.Fonts->GetGlyphRangesChineseSimplifiedCommon(); // 这个是只加载常用汉字,是参考的维基百科上的2500个汉字,但是现在的常用汉字是3500个,所以少了1000个
io.Fonts->GetGlyphRangesChineseFull(); // 这个是加载字体中所有的汉字

注意:传进来的字符必须是unicode格式,可以直接在字符串前面加u8就可以了

ImGui::Text(u8"你好");

以上接口出自:https://www.joven.top/archives/192

其实github上提供的例子里面也提供了很多加载的文件以及默认的方式吗,就在main.cpp里面:

//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);

4、显示灰色字体

效果图
ImGui::TextDisabled(u8"应用简介");

5、当鼠标悬停的时候,显示二级内容

char* desc = u8"这是一个工具类软件";
ImGui::TextDisabled(u8"应用简介");
if (ImGui::IsItemHovered())
{
    // 显示工具的提示
	ImGui::BeginTooltip();
    // 使得文字的区域可以自己控制,  但是这里我感觉更推荐使用:TextWrapped接口,之后的部分有提到他们的区别
	ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
	ImGui::TextUnformatted(desc);
	ImGui::PopTextWrapPos();
    // 结束工具提示
	ImGui::EndTooltip();
}

6、如何加载多种字体

比如:显示字符串1的时候,使用字体1,显示字符串2的时候,使用字体2

但是需要注意:

①imgui不能动态的加载字体,所以需要提前加载完成,然后使用PushFont和PopFont的接口进行转换

②当我们加载了多种字体,但是没有使用PushFont和PopFont进行设置的时候,使用的是我们第一个加载的字体

ImFont* font1 = io.Fonts->AddFontFromFileTTF("AaDouBanErTi-2.ttf", 20.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
ImFont* font2 = io.Fonts->AddFontFromFileTTF("ZhanKuWenYiTi-2.ttf", 20.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
ImFont* font3 = io.Fonts->AddFontFromFileTTF("WuXia.ttf", 20.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
ImFont* defaultFont = io.Fonts->AddFontDefault();
......
// 使用不同的字体
ImGui::Text(u8"第一种字体");
ImGui::PushFont(font3);
ImGui::Text(u8"使用Font3武侠风格字体");
ImGui::PopFont();

7、每一行的字数随着窗口大小的改变而改变

ImGui::TextWrapped(u8"当前的字体会随着窗口大小的变换,而进行每一行字数的调整");

8、每一行的字数,可以根据自己的情况进行改变,但是不随窗口的大小改变

这里我们使用了一个滑块组件来控制文字区域的大小,可以使得文字的区域随着滑块的数组进行变化,但是不随着窗口的变化进行变化

static float zoom = 50.0f;
ImGui::SliderFloat(u8"滑动以改变文字区域大小", &zoom, -20, 200, "%.3f");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImGui::PushTextWrapPos(pos.x + zoom);
ImGui::Text("this is a second, it is was used for check the rightable of PushTextWrapPos");
ImGui::PopTextWrapPos();

 

<think>嗯,用户想了解如何结合Dear ImGui来设计接口。首先,我需要回忆一下Dear ImGui的基本用法和它的特点。Dear ImGui是一个即时模式的GUI库,这意味着UI元素每一帧都需要重新构建,和传统的保留模式GUI不同。所以接口设计需要适应这种模式。 接下来,用户可能想知道如何将Dear ImGui集成到现有的项目中,或者如何组织代码结构。可能需要分步骤说明,比如初始化、主循环、UI绘制、资源管理等部分。此外,用户可能关心如何封装ImGui的功能,使其更易于使用和维护。 然后,考虑接口设计的原则。比如,保持接口简洁,模块化,避免全局状态,处理输入输出等。可能需要提到如何将UI组件封装成类或函数,如何处理用户输入事件,以及如何将数据从UI传递到应用程序的其他部分。 另外,用户可能对具体的例子感兴趣,比如如何创建一个按钮,如何处理输入框的数据,或者如何管理窗口的布局。需要提供一些代码示例,但根据系统指令,必须使用中文,并且数学公式要用$...$格式,不过这里可能不太涉及数学公式,但要注意其他格式要求。 还要注意系统级指令中的要求,比如行内数学表达式用$...$,独立公式用$$...$$,但这个问题可能不涉及数学内容,所以可能需要忽略这部分,但必须确保LaTeX语法正确。不过用户的问题是关于Dear ImGui的接口编写,可能不会涉及数学公式,所以这部分可能不需要处理,但需要保持警惕,以防万一。 用户可能需要了解如何将ImGui与不同的渲染后端和平台集成,比如OpenGL、DirectX或Vulkan。但问题更偏向于接口设计,而不是底层集成。所以可能需要集中在如何组织UI代码,如何处理回调,如何管理状态等方面。 可能的误区是用户可能没有意识到即时模式GUI的状态管理方式,需要强调每一帧都要重新构建UI,所以状态需要由应用程序维护,而不是UI库本身。接口设计时需要考虑如何将应用程序的状态传递给UI组件,并在交互时更新这些状态。 另外,用户可能希望知道如何扩展ImGui的功能,比如自定义控件或样式,但问题主要是关于接口编写,所以可能需要简要提及,但重点放在结构设计上。 总结步骤可能包括:初始化ImGui上下文,主循环中的帧处理(开始帧、构建UI、结束帧),封装常用UI组件为函数或类,处理输入事件,管理应用程序状态,以及资源清理。需要结构清晰,分点说明,并给出示例代码片段,同时用中文解释每个部分的作用。 需要确保回答符合用户可见层的结构要求,逐步引导用户理解如何设计接口,可能从基本框架开始,再逐步深入封装和模块化。同时,要确保代码示例正确,符合ImGui使用方式,比如使用ImGui::Begin和ImGui::End来创建窗口,使用ImGui::Button等函数创建控件。 可能还需要提到如何将ImGui与应用程序的事件循环结合,比如处理输入事件(鼠标、键盘),以及如何渲染UI。这部分可能涉及平台相关的代码,但用户的问题可能更关注接口设计,而不是具体的平台集成,所以可以简要说明,或者建议参考ImGui的官方示例。 最后,检查是否有遗漏点,比如错误处理、性能优化(如避免重复创建资源)、多窗口管理、UI布局技巧等。根据用户的问题深度,可能需要适当覆盖这些方面,但保持回答简洁和重点突出。</think>在结合Dear ImGui设计接口时,需遵循其即时模式(Immediate Mode)特性,并保持代码模块化。以下为分步指南: --- ### 一、基础框架搭建 ```cpp // 初始化 ImGui::CreateContext(); ImGui_ImplGlfw_InitForOpenGL(window, true); // GLFW示例 ImGui_ImplOpenGL3_Init("#version 330"); // 主循环 while (!exit) { ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); // 在此处构建UI BuildUI(); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); } ``` --- ### 二、接口封装原则 1. **状态管理** Dear ImGui不保留控件状态,需由应用程序维护: ```cpp static float slider_value = 0.0f; // 状态由外部管理 ImGui::SliderFloat("参数", &slider_value, 0.0f, 1.0f); ``` 2. **模块化封装** 将UI组件封装为独立函数或类: ```cpp void ShowControlPanel(bool* p_open) { ImGui::Begin("控制面板", p_open); if (ImGui::Button("保存配置")) { SaveConfigToFile(); // 触发自定义回调 } ImGui::End(); } ``` --- ### 三、输入/输出处理 1. **事件绑定** 通过回调函数处理交互: ```cpp static bool is_activated = false; if (ImGui::Button("启动")) { is_activated = !is_activated; OnToggleActivation(is_activated); // 自定义回调 } ``` 2. **数据传递** 使用指针或引用传递实时数据: ```cpp void UpdateGraphData(const std::vector<float>& data) { ImGui::PlotLines("曲线", data.data(), data.size()); } ``` --- ### 四、高级接口设计 1. **样式定制** 统一UI主题: ```cpp void ApplyCustomTheme() { ImGuiStyle& style = ImGui::GetStyle(); style.Colors[ImGuiCol_Button] = ImVec4(0.2f, 0.7f, 0.2f, 1.0f); style.FrameRounding = 3.0f; } ``` 2. **布局优化** 使用布局工具提升可维护性: ```cpp ImGui::BeginGroup(); ImGui::Text("状态监测:"); ImGui::SameLine(); ImGui::TextColored(ImVec4(1,0,0,1), "运行中"); ImGui::EndGroup(); ``` --- ### 五、性能优化技巧 1. **避免重复加载资源** 在初始化阶段加载纹理/字体: ```cpp GLuint texture_id = LoadTexture("icon.png"); ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("font.ttf", 16.0f); ``` 2. **条件渲染** 通过标志控制非必要UI的更新: ```cpp if (show_debug_window) { RenderDebugOverlay(); // 仅在需要时调用 } ``` --- ### 六、错误处理模式 ```cpp void SafeImGuiCall(std::function<void()> func) { try { func(); } catch (const std::exception& e) { ImGui::TextColored(ImVec4(1,0,0,1), "错误: %s", e.what()); } } // 使用示例 SafeImGuiCall([]{ DrawComplexUIComponent(); // 可能抛出异常的复杂组件 }); ``` --- ### 典型应用场景流程 1. 用户点击按钮 → 触发回调 → 修改应用状态 2. 状态变更 → 触发数据计算 3. 计算结果 → 通过指针传递至UI组件实时显示 通过这种模式,可实现数据流向:**用户输入 → 状态变更 → 逻辑处理 → UI反馈** 的闭环。 实际开发中建议参考[ImGui Demo Window](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp)的实现模式,逐步扩展自定义控件库。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值