是,但需分场景:Qt仍是2026年C++跨平台GUI最稳选择,因LGPL友好、API成熟、工具链完善;但嵌入式宜用Qt Quick,超低延迟场景需规避Qt初始化开销。

Qt 还是不是默认首选?
是,但得看场景。2026 年 Qt 仍是 C++ 跨平台 GUI 最稳的选择——不是因为它完美,而是因为它的“问题可预期”:LGPL 协议对多数开源/中小商业项目友好;QApplication、QPushButton 这类 API 经过二十年打磨,文档、报错提示、Stack Overflow 答案都够厚;Qt Creator 的 .ui 文件热重载 + qmake / cmake 双构建支持,让界面迭代不卡脖子。
但别盲目上 Qt Widgets:如果你只做嵌入式仪表盘或带触摸的工控屏,Qt Quick + QML 更合适——它用声明式语法写 UI,动画和状态切换比手动管理 QWidget 生命周期轻量得多;而如果你的程序启动要进 100ms 级别响应,Qt 的初始化开销(尤其带 QtWebEngine 时)可能直接超标。
- 常见错误现象:
QApplication::exec()卡住不动 → 检查是否漏调QApplication::setAttribute(Qt::AA_EnableHighDpiScaling)导致高分屏下事件循环异常 - 参数差异:
QPainter::drawText()在 macOS 上默认启用 subpixel rendering,Linux/X11 下需手动 setRenderHint(QPainter::TextAntialiasing) 才一致 - 性能影响:启用
QGraphicsView场景后,每帧QGraphicsItem::paint()调用次数翻倍 → 改用QQuickItem+Canvas或直接走 OpenGL 渲染更可控
wxWidgets 和 FLTK 哪个真“轻”?
FLTK 更轻,但轻得有代价;wxWidgets “重”在原生感,不是二进制体积。
libfltk.so 静态链接后通常 wxwidgets 同配置下常超 4MB——但这不是关键。真正区别在于:FLTK 所有控件都是自己画的(Fl_Button::draw() 里全是 glRectf 或 fl_line),所以 Windows/macOS/Linux 看起来像同一套皮肤;而 wxWidgets 调的是 NSButton(macOS)、CreateWindowExW(Windows)、gtk_button_new()(Linux),界面长得像系统原生,但控件行为细节(比如焦点框样式、右键菜单触发时机)各平台不统一。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 使用场景:做内网运维工具,用户只在 Windows 用,选 wxWidgets —— 用户会觉得“这软件没毛病”;做车载中控 Demo,要跑在 ARM + framebuffer 上,选 FLTK —— 它能绕过 X11/Wayland 直接绘图
- 容易踩的坑:
wxTextCtrl在 macOS 上默认禁用拼写检查,但某些 Qt 项目移植过来会误设wxTE_RICH导致输入法崩溃;Fl_Input不处理 IME 复合字符,中文输入直接丢字 - 兼容性影响:FLTK 1.3.x 对 HiDPI 支持靠
Fl::screen_scale()手动缩放,而 wxWidgets 3.2+ 自动适配,但需要链接wxbaseu_net模块才启用 DNS 解析 —— 编译时漏这个,网络请求就静默失败
Dear ImGui 算不算 GUI 框架?
不算传统意义的框架,它是“即时模式渲染层”,和 Qt/wxWidgets 不在一个维度上比较。
它不管理窗口生命周期、不封装按钮点击逻辑、不提供布局引擎——你调 ImGui::Button("Save"),它只返回 true/false 表示“此刻鼠标是否点了它”,后续逻辑全由你写。好处是:极低耦合,嵌入到游戏引擎、音视频 SDK、甚至 Vulkan 渲染循环里毫无压力;坏处是:你要自己维护状态(比如按钮按下的视觉反馈、输入框光标位置、滚动条偏移),没有 QLineEdit::textChanged 这种现成信号。
- 典型应用:
imgui_impl_glfw.cpp和imgui_impl_opengl3.cpp是必须粘贴的 glue code,漏掉任一函数,ImGui::NewFrame()就会 crash - 参数差异:
ImGui::InputText()第三个参数是缓冲区大小,不是字符串长度;传sizeof(buf)错写成strlen(buf),会导致越界写入 - 性能影响:每帧都重建整个 UI 树(
ImGui::Begin()→ImGui::End()),控件数超 500 时 CPU 占用明显上升 → 此时该用ImGui::TreeNodeEx()折叠子项,而非硬展开
别碰“自研跨平台 GUI 核心”这摊水
除非你在写航空电子显控系统、或给无 MMU 的 RISC-V MCU 驱动 LCD framebuffer,否则所有“我要造个轻量跨平台 GUI”的念头,都应该被 git clone https://github.com/qt/qtbase 或 conan install fltk/1.3.8 按回去。
真实代价不是代码量,而是那些看不见的边界 case:Windows 上 WM_DPICHANGED 消息处理不对,缩放后鼠标坐标偏移 2px;X11 下 XLookupString 返回的字符和 key event 键值混在一起,Ctrl+C 触发两次;macOS 的 NSEvent 中 modifier flags 解析漏了 CapsLock,导致大小写切换失效……这些不是 bug,是平台契约的一部分,Qt/wxWidgets 已经用十年时间填平了。
最容易被忽略的点是输入事件归一化——KEY_A 和 'a' 必须分离,Shift 状态不能靠 keyDown/keyUp 推断(因为可能被系统快捷键吞掉),而这件事在 Dear ImGui 里你得自己写 io.KeysDown[io.KeyMap[ImGuiKey_A]] = (GetAsyncKeyState('A') & 0x8000) != 0; 这种平台相关代码。


















