- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
下载 IconFontCppHeaders 里的 IconsFontAwesome6.h 文件引入到项目,然后下载 fa-solid-900.ttf 放到项目根目录,把系统字体目录下的 msyh.ttc 也移到根目录。项目文件如下:
参考 IconFontCppHeaders 的示例,字体加载的代码如下:
float baseFontSize = 30.0f;
ImFont* font = io.Fonts->AddFontFromFileTTF
(
"msyh.ttc",
baseFontSize,
nullptr,
io.Fonts->GetGlyphRangesChineseFull()
);
IM_ASSERT(font != nullptr);
// FontAwesome字体需要缩小2.0f/3.0f才能正确对齐
float iconFontSize = baseFontSize * 2.0f / 3.0f;
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_16_FA,0 };
ImFontConfig icons_config;
icons_config.MergeMode = true;
icons_config.PixelSnapH = true;
icons_config.GlyphMinAdvanceX = iconFontSize;
io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_FAS, iconFontSize, icons_config, icons_ranges);
使用方法:
ImGui::Text("%s ", ICON_FA_ALIGN_CENTER);
ImGui::Button(ICON_FA_ALIGN_CENTER " Search");
示例中所有图标都已经列出来了方便使用时查看(示例源码见文章末尾的项目链接),如下图所示:
先新建一个控制台项目,把ImGui项目 misc\fonts 路径下的 binary_to_compressed_c.cpp 文件添加到控制台项目,编译得到 binary_to_compressed_c.exe .
把需要加载的字体文件(如msyh.ttc)和上面的exe放到同一目录:
在命令行窗口通过 cd 命令导航到上面exe的目录,然后输入以下命令(任选一个):
//不压缩,使用C组,源代码大概50M
binary_to_compressed_c.exe -nocompress msyh.ttc msyh >font_msyh.c
//压缩,使用base85,源代码大概25M
binary_to_compressed_c.exe -base85 msyh.ttc msyh >font_msyh.c
因为压缩的源代码 编译时报堆栈空间不足 ,并且实际的数组会大一些,我选择的是不压缩的源代码.
把生成的 font_msyh.c 添加到自己的项目,在main文件引入字体的命名空间,然后加载字体:
#include "font_msyh.c"
ImFont* font = io.Fonts->AddFontFromMemoryTTF
(
(void*)msyh_data,
msyh_size,
30,
nullptr,
io.Fonts->GetGlyphRangesChineseFull()
);
IM_ASSERT(font != nullptr);
注意 msyh_data 里面的msyh来自命令行的窗口,注意根据字体自己取一个名字.
结论: 使用内存加载字体软件退出时会报错 ,暂时还解决不了,继续使用本地加载字体的方式 .
主窗口的标题栏是后端自带的样式且不支持修改,不能自定义样式那就只能隐藏掉,眼不见为净。 本文使用的后端是 glfw+opengl3 ,ImGui 是 docking 分支 ,其它项目的实现方法可能会有所不同.
使用 glfw 创建一个 offscreen context ,在创建窗口前加入以下代码即可:
// 设置 offscreen context 的标志位
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
// Create window with graphics context
GLFWwindow* window = glfwCreateWindow(1280, 720, "演示程序", nullptr, nullptr);
还需要 io.ConfigViewportsNoAutoMerge = true; 开启,同时 关闭ConfigViewportsNoTaskBarIcon(默认关闭) 。代码如下:
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
io.ConfigViewportsNoAutoMerge = true;
//io.ConfigViewportsNoTaskBarIcon = true;
注:如果不开启 io.ConfigViewportsNoAutoMerge 可能引起拖动窗口不小心拖动到隐藏的主窗口, 导致子窗口也隐藏的情况.
做完上面的步骤界面还是隐藏的,那是因为我们的停靠空间开启了填充标志,需要关闭:
void RenderUI()
{
//...
static bool opt_fullscreen = false;
//...
}
参考链接: IMGUI如何去掉外面窗口?
隐藏窗口后会导致一系列问题,比如关闭窗口、最大化等,下面会逐一说明.
主窗口隐藏后会遇到一个问题,程序该怎么退出?解决思路是显示停靠空间的关闭按钮,检测到关闭按钮点击后关闭主窗口。 Application.h 增加 GetMainShouldClose 函数:
#pragma once
#include "imgui.h"
namespace App
{
static bool MainOpen = true;
//程序是否退出
bool GetMainShouldClose();
//主UI函数,放停靠空间的代码
void RenderUI();
//...其它代码
}
Application.cpp 还需要改动 RenderUI 函数:
bool GetMainShouldClose()
{
return !MainOpen;
}
void RenderUI()
{
bool* p_open = &MainOpen;
static bool opt_fullscreen = false;
//...其它代码
ImGui::Begin("演示程序", p_open, window_flags);
//...其它代码
}
然后再main函数的 App::RenderUI() 后面判断是否退出程序:
//...
App::RenderUI();
if (App::GetMainShouldClose())
{
//关闭窗口,也可以做一些退出确认操作
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
//...
原本的 HideTabBar 有问题,如果有新窗口停靠到中心位置会导致新窗口被覆盖隐藏,只能通过重置布局恢复。所以标题栏最好不隐藏,只隐藏前面的三角符号,这样也能允许用户自己拖动窗口。 优化代码如下:
void HideTabBar()
{
ImGuiWindowClass window_class;
window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoWindowMenuButton;
//window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoTabBar;
ImGui::SetNextWindowClass(&window_class);
}
窗口最大化需要知道屏幕的尺寸,这一步涉及到具体的后端代码,需要先在main文件中获取屏幕尺寸.
在main函数前实现 GetScreenSize 函数,代码如下:
static void GetScreenSize(int &width, int &height)
{
//屏幕数量
int monitorCount;
GLFWmonitor** pMonitor = glfwGetMonitors(&monitorCount);
int screen_x, screen_y;
for (int i = 0; i < monitorCount; i++)
{
const GLFWvidmode* mode = glfwGetVideoMode(pMonitor[i]);
//屏幕大小
screen_x = mode->width;
screen_y = mode->height;
}
width = screen_x;
height = screen_y;
}
然后在main函数中将主窗口的大小设置为屏幕大小一致,代码如下:
//获取屏幕尺寸
int width, height;
GetScreenSize(width, height);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
// Create window with graphics context
GLFWwindow* window = glfwCreateWindow(width, height, "演示程序", nullptr, nullptr);
在App::RenderUI函数中的停靠空间渲染前设置空间大小,并在主题切换代码后加上大小切换的代码,代码如下:
//...其它代码
//设置最大化、最小化
static bool IsMaximized = true;
static bool LastMaximized = true;
ImVec2 screenSize = ImGui::GetIO().DisplaySize;
if (IsMaximized)
{
if (LastMaximized != IsMaximized)
{
LastMaximized = IsMaximized;
}
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(screenSize);
//隐藏标题栏
//window_flags |= ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
}
else
{
if (LastMaximized != IsMaximized)
{
LastMaximized = IsMaximized;
ImGui::SetNextWindowPos(ImVec2(screenSize[0]*0.1, screenSize[1] * 0.1));
ImGui::SetNextWindowSize(ImVec2(screenSize[0] * 0.8, screenSize[1] * 0.8));
}
}
ImGui::Begin(ICON_FA_ANCHOR "演示程序", p_open, window_flags);
//...其它代码
//增加主题切换
if (ImGui::BeginMenu(ICON_FA_THERMOMETER "主题(Other)"))
{
if (ImGui::MenuItem("暗黑(Dark)")) { ImGui::StyleColorsDark(); }
if (ImGui::MenuItem("明亮(Light)")) { ImGui::StyleColorsLight(); }
if (ImGui::MenuItem("经典(Classic)")) { ImGui::StyleColorsClassic(); }
ImGui::EndMenu();
}
//增加窗口切换
if (ImGui::BeginMenu(ICON_FA_TV "窗口(Windows)"))
{
if (ImGui::MenuItem(ICON_FA_WINDOW_MAXIMIZE "最大(Max)")) { IsMaximized = true; }
if (ImGui::MenuItem(ICON_FA_WINDOW_RESTORE "默认(Default)")) { IsMaximized = false; }
ImGui::EndMenu();
}
文中的主要的优化措施就是 引入字体图标 、 隐藏主窗口 ,结合前一篇的文章,ImGui基本的功能都已经涉及到了.
文中还有一些遗留问题,比如:
目前的内容对于简单的项目来说基本够用,后面应该不会再继续更新ImGui相关的内容了,等项目中遇到问题再说.
项目源码链接: 提取码: tv7n 。
最后此篇关于ImGui界面优化:使用图标字体、隐藏主窗口标题栏的文章就讲到这里了,如果你想了解更多关于ImGui界面优化:使用图标字体、隐藏主窗口标题栏的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一家小型非营利组织的技术总监,我们正在制作一个新网站。我们提出了几个不同主页设计的模型,需要接收董事会成员的意见。是否有在线应用程序/程序/框架可以接收和组织用户评论?我正在寻找允许在查看页面时发
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我阅读了很多关于 java 接口(interface)的文章。我知道你可以实现多态性和其他伟大的东西(函数指针等)。我有理论知识,但有一点点或什至没有。我一直在使用很多已经制作好的界面,比如“Runn
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以
我正在尝试在 Windows 7 上编写一个 python 脚本来与我的 Wacom Bamboo Pen 数位板交互。 Wacom 建议使用 WinTab API,它工作正常,但不适用于我的应用程序
我正在研究一种远程访问有关 Linux 服务器统计信息的方法,即 conky会显示。 有没有办法与 conky 交互并获取它显示的统计信息?如果没有,您能否推荐一种获取此类统计数据的好方法? (C/C
将所有这些代码包装在 UI: do { } block 中的原因是什么?我在哪里可以获得关于它的明确说明? UI: do { backgroundButton.setImage(UIImage
我需要将 R 连接到某些 C# 应用程序。我安装了 rscproxy_1.3 和 R_Scilab_DCOM3.0-1B5 添加了对 STATCONNECTORCLNTLib、StatConnecto
我正在尝试遍历接口(interface)片段以通过 id 查找我的特定结构并更改属性。 type A struct { ID ID Steps []Step } type Ste
我有两种不同格式的相同界面,一种是键由低破折号分隔的 JSON 格式,另一种是 javascript camelCase 格式: JSON 格式: interface MyJsonInterface
操作系统:Linux。 我正在尝试寻找可能的方法来为我的嵌入式系统实现 Web 界面。 目前有一个外壳(基于文本)和一小组命令用于查询设备。 我是网络开发新手,我的问题是: 我必须使用什么网络服务器?
我正在尝试运行基于 Mechanical Turk Qualtrics 的调查,并且需要一些似乎可以通过 Mechanical Turk API 使用的功能,例如 custom Qualificati
我见过漂亮的 MetroTwit 界面 http://www.metrotwit.com/ ;我想知道使用了哪些 WPF 组件来尝试重现它。 最佳答案 MetroTwit 设计师在这里:) 所有的控件
我有一个小问题。我需要将 Hadoop Web 界面与我们的 Web 应用程序集成。我只需要一个 Hadoop 接口(interface),我们可以在其中运行一些 hadoop 命令,例如 1
假设我有这个 JavaScript 函数: function updateMainBuff(buff) { // do some stuff } 我的
我试图找出一个窗口是否属于当前的虚拟桌面。 我从 winapi 中找到了 VirtualDesktopManager 类,但即使根据 here 它应该位于“shobjidl.h” header 中,当
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 8年前关闭。 Improve this
我的 Tkinter GUI 界面有问题。文本不会在 shell 中打印,但如果将 Entry 放置在第一个 tk 窗口 get() 中,它就可以工作...帮助我吗? 这是我的代码: import o
我有一个在 MATLAB 中实现的随机微分方程组。只有 4 个变量与 Euler-Maruyama 集成,所以没有什么太花哨的......不过,技术细节对于这个问题并不重要。 您建议我如何构建一个 W
对于我创建的插件,我想添加一个网络界面,您可以从中更改设置并执行一些简单的数据操作。此数据操作应通过 sqlquerys 完成。我正在使用 sqlite 数据库,这就是问题开始的地方: 网站(serv
我是一名优秀的程序员,十分优秀!