ElaWidgetTools 这套 Qt 控件库最近在开源社区里讨论度确实不低。很多朋友都是先看到项目主页那一套漂亮的截图——左侧导航栏、圆角卡片、通透的亚克力效果、一键切换浅色深色主题——然后忍不住 clone 下来想跑起来看看。结果不少人卡在编译这一步:要么打开项目发现没有.pro文件,要么报一堆 CMake 错误,要么提示缺少某个 Qt 模块。这篇文章我就按自己的实操过程,把 ElaWidgetTools 的编译、运行、示例效果和常见问题一次性梳理清楚,照着走基本能跑通。
我本人是从 Qt 5.15.2 + MSVC2019 64 位这套组合入手的,前后踩了不少坑,最后梳理出了一条相对顺畅的路线。本文会覆盖环境准备、源码获取、三种编译方式、示例运行、常见报错排查这几个部分,适配 Windows 平台,也顺带提一下 Qt 6 和 Linux 环境需要注意的点。无论你是想把它集成进自己的项目,还是单纯想体验一下效果,这篇文章都适合从头到尾读一遍。
1. 项目解析与核心价值
1.1 这到底是一套什么库
ElaWidgetTools 是 GitHub 上一个开源的 Qt 样式控件集合,作者是 Liniyous,从项目名称就能看出来:Ela(风格代号)+ Widget + Tools。它的目标不是做一个业务框架,而是提供一整套现代感十足的 Qt Widgets 控件和窗口方案。如果你用过 Fluent Design 风格的库,再看 ElaWidgetTools 会觉得很亲切,但它不是简单模仿,而是把圆角、阴影、导航、主题切换这些元素做成了开箱即用的组件。
核心组件大概是这几类:
| 组件 | 作用 |
|---|---|
| ElaWidget / ElaWindow | 基础窗口和带导航栏的主窗口,支持阴影、圆角、拖拽移动 |
| ElaDxWindow / ElaAcrylicWindow | 支持 DirectX 和亚克力效果的窗口,适合做视觉效果展示 |
| ElaNavigation | 左侧导航栏,支持分组、折叠、切换回调 |
| ElaContent / ElaSettingCard | 内容区容器和设置卡片样式 |
| ElaToggleSwitch / ElaPushButton 等 | 一系列自带样式的控件 |
另外项目里除了 C++ Widget 版本,现在也在往 QML 方向扩展,比如ElaQML相关目录。但坦白说 QML 版本目前还不算完整,我更推荐先跑通 C++ Widget 版。它的核心价值在于:你不用再从零开始抠 QSS 和窗口样式,直接引用这个库,就能快速搭出一个界面现代、交互流畅的桌面应用外壳,特别适合做工具类软件、配置面板、多媒体播放器这类产品。
1.2 为什么值得你花时间编译一次
很多人看到“开源控件库 + 编译示例”会觉得麻烦,但我的看法是,这个项目值得你花半小时把它跑起来,原因有两个。
第一个原因是它确实能省工作量。我自己在做内部小工具时,最烦的就是把 QWidget 默认那个灰扑扑的样式改成顺眼的界面。要么手写一大段 QSS,要么引入一堆样式的动态库,两者维护成本都不低。ElaWidgetTools 把导航、主题、卡片这些高频场景封装好了,效果统一,改动一处全局生效。你后面做同类界面时完全可以直接复用。
第二个原因是它的代码本身就值得学习。项目内部用到了样式表动态编译、事件过滤、绘制事件重写这些技巧,窗口特效部分还涉及 Windows 原生 API 的调用链。你把它的源码读一遍,对“QWidget 到底怎么实现无边框透传阴影”“侧边导航切换按钮状态是怎么刷新的”这类问题会有一个非常直观的理解。这种收获是单独靠查文档得不到的。
2. 编译前环境准备
2.1 版本选型与工具链选择
先说结论:如果你是第一次跑,我建议用Qt 5.15.2 + MSVC2019 64 位 + CMake 3.20 以上这套组合。项目 README 里也写了推荐 Qt 5.15.2 以上或 Qt 6,但 Qt 5.15.2 的坑最少,环境也最好凑。我这里说的环境不是“随便哪个 Qt 版本都行”,而是要注意几个点。
第一,编译器建议用 MSVC,而不是 MinGW。这不是说 MinGW 一定编译不过,而是 ElaWidgetTools 依赖的两个开源库 QHotkey 和 qwindowkit,在 MSVC 下的兼容性明显更好,尤其是窗口阴影和系统级消息钩子相关代码。Windows 上如果用 Qt Creator 选了 MinGW Kit,编译期不一定会报错,但运行期窗口特效有时会异常,排查起来很浪费时间。你那个机器上如果同时装了 32 位和 64 位编译器,记得统一选 64 位,项目默认按 64 位输出。
第二,CMake 版本不能太老。早期 CMake 3.16 虽然也能识别 Qt5 的 CMake 模块,但对 qwindowkit 里的一些 target 特性和策略处理不友好,我在 3.14 版本上跑过一次,配置阶段就报了一堆CMake unknown policy的错误。建议直接装 3.24 或 3.27 以上的版本,用 CMake GUI 或者命令行都行。
第三,Qt 安装组件要选全。只装MSVC 2019 64-bit这一项往往不够,如果后续你打开项目自带的示例工程,里面涉及加载网页或高级功能,会用到 WebEngine,这时候你要在 Qt 安装管理器里把Qt WebEngine组件勾上。很多报unknown module(s) in qt: webenginewidgets的朋友,就是安装阶段漏了这个组件,后面怎么折腾代码都解决不了。
2.2 获取源码与子模块处理
ElaWidgetTools 的源码在 GitHub 上直接能搜到,仓库地址我不在这里贴链接,你搜索ElaWidgetTools就能找到。下载方式有两种,第一种是直接 Download ZIP,第二种是用 git clone。我推荐第二种,因为仓库引用了两个外部子模块:QHotkey 和 qwindowkit。如果用 ZIP 下载,这两个子模块的目录是空的,CMake 配置时就会报找不到qwindowkit的 target。
clone 命令可以这样写:
git clone --recursive https://github.com/Liniyous/ElaWidgetTools.git如果你已经用 ZIP 方式下载了,或者 clone 时忘了加--recursive,也不要紧,在项目根目录执行:
git submodule update --init --recursive执行完之后,检查一下ElaWidgetTools/imports/qwindowkit或者仓库中对应目录里是不是真的有源码文件。如果子模块拉不下来——国内网络环境容易出现这种问题——不要干等,去 GitHub 上分别搜 QHotkey 和 qwindowkit 的仓库,手动下载后解压到对应目录。这里有个小坑:手动放置的目录层级必须和.gitmodules里配置的路径完全一致,否则 CMake 还是会找不到。
注意:qwindowkit 是跨窗口框架的库,Windows 上编译时需要系统库
dwmapi.lib、user32.lib,这些在 MSVC 环境里是标配,不用额外下载。如果 CMake 报告找不到系统库,绝大多数情况是你没用 MSVC 的开发命令行环境,后面会细说。
3. 详细编译路线:从 Qt Creator 到命令行
3.1 路线 A:Qt Creator + CMake 配置
这是最直观的方式,也是我建议新手先走的路。打开 Qt Creator,选择“打开项目”,定位到ElaWidgetTools/CMakeLists.txt,Qt Creator 会识别这是一个 CMake 工程。首次打开会弹出一个配置 Kit 的界面,这个时候要重点检查:
- Kit 名称里有没有
MSVC2019 64bit或者MSVC2022 64bit? - Qt 版本是不是你刚装的 5.15.2?
- 构建目录是不是默认的
build-ElaWidgetTools-...这种影子构建目录?
如果 Kit 列表里全是 MinGW,说明你安装 Qt Creator 时只编译了 MinGW 工具链,或者没有检测到 MSVC。解决办法不是重装 Qt Creator,而是打开“工具 -> 选项 -> Kits -> 编译器”,手动添加 Microsoft Visual C++ 编译器。编译器中可执行文件一般位于 Visual Studio 安装目录的VC/Tools/MSVC/<版本>/bin/Hostx64/x64/cl.exe。添加完成后,在 Qt Versions 页面确认 5.15.2 对应的 qmake 路径,再回到 Kits 里新建一套 MSVC + Qt 5.15.2 的组合。
配置完成后,直接点左下角的绿色运行按钮。第一次构建比较慢,要编译 QHotkey、qwindowkit、ElaWidgetTools 本体,再链接示例程序。如果一切正常,最后的输出窗口会显示几行目标文件路径,并自动弹出示例窗口。如果直接构建就报错,建议跳过 Qt Creator 的日志,先看 CMake 配置阶段是否通过,再排查具体错误。
3.2 路线 B:命令行 CMake 构建
更贴近团队协作场景的是命令行构建。Windows 下不要直接打开普通的 CMD 窗口去跑 cmake,因为 cl.exe、link.exe 这些编译器的环境变量还没配置。正确姿势是先从开始菜单打开x64 Native Tools Command Prompt for VS 2019/2022,这个快捷方式会把 Visual Studio 的编译环境全部加载好。然后进入到 ElaWidgetTools 源码目录,执行:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_PREFIX_PATH=C:/Qt/5.15.2/msvc2019_64CMAKE_PREFIX_PATH很关键,它告诉 CMake 去哪里找 Qt5Config.cmake。如果你装在 D 盘或者 Qt 6,路径就对应修改。这一步通过后,再执行:
cmake --build build --config Release --target ElaWidgetToolsDemo--target指定编译哪个目标。ElaWidgetTools 仓库里在 CMakeLists 中会生成几个 target,最基本的列表大致是:ElaWidgetTools(库本体)、ElaWidgetToolsDemo(综合示例)、ElaWidgetToolsTest(单元测试)。如果你只是想先看效果,编ElaWidgetToolsDemo就够了。
提示:命令行构建完成后,可执行文件在
build/Release/ElaWidgetToolsDemo.exe。直接双击运行前,如果弹出缺少 Qt5Core.dll 之类的错误,别忘了把 Qt 的bin目录加入 PATH,或者用windeployqt工具把运行依赖拷贝到 exe 旁边。命令是windeployqt build/Release/ElaWidgetToolsDemo.exe。
3.3 示例工程与实际运行效果
编译通过之后,重点来了:示例程序能跑出什么效果,以及怎么验证这个库确实工作了。ElaWidgetToolsDemo 启动后,你会看到一个主窗口,左侧是导航栏,中间是内容区域。这个窗口不是普通的 QMainWindow,它是 ElaWindow 的子类,所以窗口周边有阴影和圆角处理,放大缩小、贴边拖拽都比较顺滑。
你可以依次验证以下几项:
- 左侧导航栏有几个分组,点击分组内的菜单项,右侧内容区会切换到对应的示例页面,切换过程有过渡动画。
- 窗口顶部或设置区有主题切换开关,在浅色和深色之间切换时,控件颜色、卡片背景、文字颜色会整体变化。这个效果的实现核心是 ElaApplication 和一组动态的属性标记,不是简单给整个窗口换 QSS。
- 部分示例页里有按钮、开关、滑条、输入框等控件,这些控件的 hover、按下、禁用状态都做过样式定制,你可以直观感受到控件库的完成度。
如果运行后窗口白屏或者控件布局错乱,优先检查是不是缩放比例的问题——示例程序默认开启了高 DPI 支持,如果你的显示器缩放是 125% 或 150%,某些旧的绘制逻辑可能出现偏移。这个问题在 Qt 6 下基本不存在,Qt 5.15.2 下偶尔会遇到,更新显卡驱动或改用 Qt 6 分支可以解决。
4. 自己项目里如何接入这个库
4.1 以 CMake 方式引入依赖
跑通示例之后,下一步自然是把它用的自己的项目里。最干净的方式是 CMakeadd_subdirectory,这样不用提前安装库到系统目录,直接把你 clone 下来的 ElaWidgetTools 目录放成项目子目录,在 CMakeLists 里加两行:
add_subdirectory(ElaWidgetTools) target_link_libraries(your_target PRIVATE ElaWidgetTools)编译时 CMake 会顺带把 QHotkey 和 qwindowkit 编译出来,你不需要手动去配置它们的头文件路径。有一点需要注意:ElaWidgetTools 的 CMakeLists 里会设置一些编译选项,比如CMAKE_CXX_STANDARD 17,如果你的项目对 C++ 标准还有别的约束,务必在add_subdirectory之前提前设置,否则可能覆盖你的全局配置。
如果你想引用的是动态库版本,Windows 下会生成ElaWidgetTools.dll,需要在运行时把 DLL 放到 exe 同级目录。如果嫌麻烦,可以把BUILD_SHARED_LIBS设为 OFF,编译成静态库。静态库模式下所有依赖都打进 exe,发布时反而省心,但要注意 QHotkey 和 qwindowkit 也必须是静态编译,且整个项目保持 Release/Debug 一致,不然链接阶段很容易报LNK2038这类运行时库不匹配的错误。
4.2 模块拆分与按需使用
不是所有控件都适合无脑引入。ElaWidgetTools 虽然是一个整体库,但代码里分模块做得比较清楚。如果你的场景只需要某一个开关按钮,完全可以只复制对应的头文件和源文件,不必把整个 CMake 工程都引进来。不过我不建议新手这么做,因为控件之间有隐式依赖,比如主题切换依赖ElaApplication里的单例和事件过滤器,单独复制一个按钮类不带上这套基础设施,编译期可能通过,运行期样式却是错的。
我自己的经验是:第一次接入老老实实用整个库,把窗口框架跑通了,再考虑裁剪。如果你确实觉得整个库偏重,可以先只引入ElaApplication、ElaWindow、ElaNavigation这几个核心类,辅助控件后续按需加。这样既保住了导航和主题的核心体验,又不至于把全部控件堆进来。
5. 常见问题与排查技巧实录
5.1 unknown module(s) in qt: webenginewidgets
这个报错出现的频率极高,几乎每个在中文社区提问的帖子下都能看到。很多人一看到 unknown module 就怀疑是项目工程的模块拼写错误,或者想换一套北向解析配置,但其实原因非常简单:你安装 Qt 时没勾选 WebEngine 模块。Qt 的安装管理器里,MSVC 版本的 Qt 5.15.2 项下有一个组件列表,默认可能不含 WebEngine,你需要展开勾选自己需要的模块,再重新安装。
重新安装后,用 5.15.2 对应的 qmake 检查一下模块列表:
C:/Qt/5.15.2/msvc2019_64/bin/qmake -query QT_INSTALL_MODULES补充安装完成再编译,这个报错就不会再出现了。另外,如果你是在 macOS 或 Linux 上遇到这个报错,处理方式类似,用各自的安装管理器勾选 WebEngine 相关包即可。
5.2 找不到 VCPKG 或 qwindowkit 相关依赖
在 Windows 上编译 ElaWidgetTools,经常会看到 CMake 报Could not find a package configuration file provided by "qwindowkit",或者set(QT_FEATURE_xxx)相关错误。这里分两种情况。第一种是子模块没拉全,这个前面已经说过了,用git submodule update --init --recursive补上。第二种是拉下来了但 CMake 版本太低,qwindowkit 里用了比较新的 CMake 命令,比如cmake_policy(SET CMP0091 ...),3.15 以下的版本无法识别。升级 CMake 到 3.21 以上基本能解决。
如果用了 VCPKG 管理第三方库,还可能出现 Qt 目录互相干扰的问题。建议编译 ElaWidgetTools 时先暂时关闭 VCPKG 的CMAKE_TOOLCHAIN_FILE变量,或者明确指定 Qt 路径,避免两个包管理器打架。
5.3 编译通过但运行崩溃
这是我遇到过比较隐蔽的问题:示例程序编译得很顺利,打开也正常,但关闭窗口的瞬间偶尔崩溃,或者切换页面时程序闪退。排查下来两个原因最常见。第一个是 Debug 和 Release 混用,比如库本体编译成 Debug,但 demo 跑 Release,Qt 的调试运行时和发布运行时混在一起,内存释放时就会出问题。第二个是主题样式对象的生命周期问题,ElaApplication 里如果有全局单例提前释放,面板窗口析构时仍在访问样式对象,触发野指针。
一次常规的排查步骤供你参考:
- 检查所有第三方库是否都是 Debug-Debug、Release-Release 配对。
- 运行程序前,在 Qt Creator 中把构建配置切到 Release,别用 Debug。
- 如果崩溃现场有报错信息,先看是不是在
ElaApplication::sync或者QWindow析构附近出现。 - 尝试在 main 函数里延迟创建窗口,确保
QApplication完全初始化后再加载组件。
这个问题的坑在于不是每个人都会遇到,如果你一直很稳,说明运气好;如果你遇到了,重点往运行时报版本一致性方向去查,方向对了就快了。
5.4 其他热点情况速查表
| 现象 | 主要原因 | 处理建议 |
|---|---|---|
| 构建时提示找不到 Qt5Config.cmake | CMAKE_PREFIX_PATH没指向 Qt 的 msvc 目录 | 显式设置-DCMAKE_PREFIX_PATH=C:/Qt/5.15.2/msvc2019_64 |
| MSVC 工具链没反应 | Qt Creator 的 Kit 未配置 MSVC 编译器 | 在 Kit 设置里添加 cl.exe,确保 AND 选择 x64 |
| 运行窗口无阴影/无圆角 | 系统特效关闭或显卡驱动兼容问题 | 打开 Windows 特效,更新显卡驱动 |
| 导航图标不显示 | Qt 资源文件未编译进库 | 清空 build 目录后重新生成,确认没有跳过资源编译 |
| 提示缺少 D3D 相关 dll | 旧系统缺少 DirectX 运行库 | 安装 DirectX 9 运行库,或改用非 Dx 的窗口类 |
6. 一些个人的踩坑总结
最后聊点我自己的体会。ElaWidgetTools 这个项目整体质量在开源 Qt 控件库里算比较高的,文档虽然不算特别全,但示例代码本身就很值得看。我建议你拿到代码后,不要只满足于让它跑起来,花点时间把ElaWindow.cpp和ElaNavigation.cpp读一遍,这两个文件基本能回答你“Qt 无边框窗口怎么做阴影”“导航按钮选中态怎么同步”这些经典问题。
如果后续想在项目里长期用它,有一点要提前想清楚:项目迭代速度不算慢,主分支偶尔会有接口调整,你如果直接锁死某个 commit 或者定期跟着 main 走,都要在代码里做好版本标记。我的做法是把依赖库的版本固定成一个 fork 的 tag,自己内部统一从那个 tag 拉在,避免大家的环境不一致。
本机如果条件允许,我建议你在 Qt 5.15.2 上跑通后再花点时间试试 Qt 6 分支。Qt 6 下窗口高 DPI 和渲染行为更规范,适配高分辨率屏幕的效果明显更好。两个版本之间切换时,记得把 build 目录单独分开,不要混着编译。按照上面的步骤走,顺利的话从 clone 到看到示例窗口大概只需要二十分钟,剩下玩各种控件就随你折腾了。