噢等等,那个是脏区重绘机制吗?没错这款库竟然支持脏区重绘,这使得它在处理复杂场景时能够保持良好的性能(其实由于SDL2每次Render Present 都需要交换整个缓冲区,所以性能会受到影响,导致其可能没有其他GUI库比如WinUI占用少。但这起码是SDL2这种蹩脚轮子能写出来的最好的带脏区重绘优化的GUI库了)
- 易于做跨平台兼容
- 支持脏区重绘优化,性能比每帧全部重画要好一点(SDL2对性能优化一点也不友好,我已经尽力了)
- 支持自定义控件
- 支持更换配色方案(?我不知道这算不算值得说的优点,但还是加上吧)
- 内置 15+ 种常用控件,开箱即用
- 依赖极简:只需 SDL2 / SDL2_ttf
- 没排版引擎(这将是硬伤,等我有空和GenFromXML功能一起出)
- 目前仅面向 Windows(内部使用了 Win32 API 实现下拉弹窗等特性)
| 控件 | 类名 | 说明 |
|---|---|---|
| 垂直滚动条 | ScrollBarV |
上下页面翻动 |
| 水平滚动条 | ScrollBarH |
左右页面翻动 |
| 控件容器 | ControlBox |
类似 Windows 子父窗口的概念,自动滚动 + 滚动条 |
| 按钮 | PushButton |
最基础的控件之一 |
| 静态文本 | StaticText |
虽然叫 Static,但可以修改显示文本 |
| 链接文本 | LinkText |
带下划线的可点击文本 |
| 输入框 | InputBox |
单行/多行文本输入(整个库最复杂的控件) |
| 复选框 | CheckBox |
三态:勾选 / 不勾选 / 部分勾选 |
| 开关 | ToggleButton |
本质上是更好看的复选框 |
| 单选按钮 | RadioButton |
与同 ControlBox 内其他单选按钮互斥 |
| 图片框 | PictureBox |
支持 5 种图片填充方式 |
| 滑动条 | Slider |
数值调节 |
| 下拉列表框 | ComboBox |
自绘 PopupWindow 弹窗下拉 |
| 进度条 | ProgressBar |
三态:正常 / 处理中 / 暂停 |
| 选项卡 | TabControl |
多标签页,支持关闭、拖动重排、四个方向 |
QRCodeBox--- 二维码控件,基于 QR-Code-generator 库实现(需定义ENABLE_QRCODE_MODULE宏)
#define NOMINMAX
#include "Fgui\Fgui.hpp"
int main(int,char**){
//初始化SDL
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
TTF_Init();
SDL_Window* window = SDL_CreateWindow("Minimal Example",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,1000,800,SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Rect top_relative_rect = {0,0,1000,800};
SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);
//准备GUI
FontEx font({"font.ttf"});
//创建根容器
std::shared_ptr<ControlBox> cb = std::make_shared<ControlBox>(SDL_Rect{0,0,1000,800});
//创建一个按钮
auto button = cb->PushbackControl("hello", std::make_shared<PushButton>("Hello Fgui!",&font,128,SDL_Rect{0,0,0,0}));
//居中显示
button->default_rect.x = 500 - button->default_rect.w / 2;
button->default_rect.y = 400 - button->default_rect.h / 2;
//设定点击回调
button->actions.OnClick = [](PushButton *){printf("Hello Fgui!\n");};
//SDL事件循环必须事项
SDL_Event eve;
Timer fps_lim(60);
bool running = true;
//SDL事件循环
while(running){
//处理SDL事件
while(SDL_PollEvent(&eve)){
if(eve.type == SDL_QUIT) running = false;
if(SDL_GetWindowID(window) == eve.window.windowID) cb->MaintainEvent(&eve,{0,0,1000,800});
}
//调用Tick回调
cb->MaintainTimer({0,0,1000,800});
//读取脏区域
SDL_Rect dirty_rect = cb->GetInvaildRect(top_relative_rect);
//判断是否有脏区域
if(dirty_rect.w != 0 && dirty_rect.h != 0){
//脏区域重绘
SDL_SetRenderDrawColor(renderer,
cb->GetColorKit().BackgroundColorDarker.r,
cb->GetColorKit().BackgroundColorDarker.g,
cb->GetColorKit().BackgroundColorDarker.b, 255);
SDL_RenderFillRect(renderer, &dirty_rect);
cb->MaintainRender(renderer, top_relative_rect);
SDL_RenderPresent(renderer);
}
fps_lim.Delay();
}
//释放SDL资源
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
return 0;
}项目使用 CMake,提供 4 个预设(MinGW Makefiles):
# 仅测试程序 main.exe(Debug / Release)
cmake --preset debug
cmake --build build/debug --target fast_gui2
# 测试程序 + 示例程序
cmake --preset debug-examples
cmake --build build/debug-examples --target examples可执行文件统一输出到 bin/ 目录,注意启动程序时指定工作目录为 res/ 目录,否则会缺DLL缺资源。
详细的库文档请见 docs/wiki/:
- 快速开始
- 构建与项目结构
- 核心架构(控件基类 / 脏区重绘 / 事件系统)
- ControlBox 与布局
- 控件参考(上):基础控件
- 控件参考(下):复杂控件
- 图形绘制 API
- 配色与主题
- 自定义控件
- 示例教程:文本编辑器
- 常见问题与陷阱
- 支持排版引擎,用于自动布局控件,属性类似CSS
- 支持GenFromXML功能,用于从XML文件加载并生成控件(It saves your hands! - 指可以AI生成XML文件,而不是手动写)
- 支持跨平台(Linux平台)
真的有人试吃我的屎山代码吗?这玩意就是我周末抽空写的一个学习项目而已。但是我会试图让它更好的。
:) GL 2026-08-12