VS2019 下编译 KDDockWidgets 动态库:从源码到 Qt 工程集成指南
简介KDDockWidgets是Qt生态中功能完善的可停靠窗口Docking组件这套资源为基于VS2019与Qt5.15.264位预编译的动态库和完整源码面向需要在Qt Quick或Widgets应用中实现灵活窗口停靠布局的开发者。整个压缩包为RAR格式共956个文件约51.56MB其中包含279个头文件、139个C源文件、12个DLL动态库及配套LIB/EXE产物还有QML界面资源、JSON配置、CMake脚本与PDF说明文档等便于按需查阅和二次开发。需要特别留意动态库严格区分为Quick和QWidget两种版本对应include头文件不能混用并且仅支持64位编译环境32位工程不可使用。资源内附带两个演示demo每个demo均包含KDDockWidgets工程文件夹开发者可直接将KDDockWidgets.pri引入自己的项目省去复杂配置也能对照示例快速掌握集成方法与布局效果。目前已有789人学习下载配合作者博客中的讲解可更深入地理解停靠窗口的集成细节和常见问题。1. VS2019 编译 KDDockWidgets 这件事卡住过很多人在 Windows 桌面端做多窗口应用绕不开“停靠布局”这套交互侧边栏可以拖出来、贴回去、Tab 合并外观像 Visual Studio 自己的面板。自己写一套能商用的停靠框架少说两到三个月而且拖拽、吸附、布局保存这些细节特别容易烂尾。KDDockWidgets 就是专门解决这个问题的开源库底层基于 Qt性能与交互都贴近生产级。但这个库不直接给 VS 用户发编译好的二进制官方默认只给 QMake/CMake 的源码工程导致大量开发者卡在“源码在手编不出 dll”这一步——Qt 版本不对、CMake 找不到 Qt、编译器工具集不匹配任何一个环节都能让编译失败。这篇笔记的目标就一个把 KDDockWidgets 在 VS2019 下的编译链路、动态库产物和集成步骤一次讲透照着能产出 KDDockWidgets.dll并能被自己的 Qt 工程正常加载。2. KDDockWidgets 是什么为什么值得先花半小时理解它的源码结构2.1 停靠框架要解决的核心问题停靠框架Docking System做的事情是把一个窗口区域抽象成可停靠的 DockWidget用户可以拖动它到主窗口的上下左右边缘也可以让它浮动成独立窗口还可以多个 DockWidget 叠成 Tab 页。KDDockWidgets 的核心卖点是“用 Qt 标准控件实现不依赖第三方重量级组件”而且它把 MainWindow、DropArea、DockWidget 这几个类拆得很清楚改行为比 QMdiArea 和 QDockWidget 默认形态灵活得多。选 KDDockWidgets 而不是 QDockWidget主要是因为 QDockWidget 的浮动窗口和布局恢复能力比较弱拖动反馈也粗糙。KDDockWidgets 支持多窗口间互相拖拽停靠这在 Qt 原生控件里是做不到的。另外它的 License 是 LGPL动态链接的情况下可以闭源商用这也是很多团队选它的关键原因。2.2 源码目录里藏着的“三件套”core、dockwidget、multisplitter从 GitHub 拉下来的 KDDockWidgets 源码顶层目录基本是 examples、src、tests 这三个。src 下面要盯住几个子目录Core 是核心逻辑拖拽、状态管理DockWidget 是各个 Dock 组件MultiSplitter 是停靠区域的布局算法。编译之前最好先把 MultiSplitter 这个目录翻一下里面是窗口分割的几何计算后续你要是想改“最小停靠宽度”“浮动窗口透明度”这类行为改的就是这里。源码根目录的 CMakeLists.txt 是整个工程的入口它通过add_subdirectory把 Core、DockWidget 等模块组装起来。VS2019 编译走 CMake 是最稳的路径因为 KDDockWidgets 对 qmake 的支持虽然还在但新特性基本都优先落在 CMake 上。2.3 动态库与静态库的选择不是越多越好编译 KDDockWidgets 时CMake 会产出一组库文件包括核心库 KDDockWidgets或带 Qt 主版本后缀的 KDDockWidgets_Qt6、KDDockWidgets_Qt5如果你打开的是多窗口示例还会编出 KDDockWidgets 的 examples 可执行文件。选择动态库而不是静态库最直接的好处是主程序体积小KDDockWidgets 的 bug 修复后只要替换 dll 就能生效不用重新链接整个 exe。动态库的代价是部署时要多带一个 dll还要保证 Qt 的运行库Qt6Core.dll、Qt6Gui.dll、Qt6Widgets.dll路径能被找到。你要是图省事选静态库编译时间会更长而且链接时经常遇到“符号重定义”之类的问题反而更难排查。所以我的建议是项目发布用动态库调试阶段也保持动态库保持开发与生产环境一致。3. 从源码到 dll用 CMake 在 VS2019 下产出 KDDockWidgets 动态库3.1 环境准备确认三样东西缺一不可开始编译前先把环境清单过一遍。第一是 Visual Studio 2019必须安装“使用 C 的桌面开发”工作负载里面包含 MSVC v142 工具集和 Windows SDK。第二是 CMakeVS2019 自带 CMake 组件也可以用 cmake.org 的独立安装包版本建议 3.16 以上。第三是 QtKDDockWidgets 依赖 Qt5 或 Qt6编译前必须用 Qt 官方安装器装好对应版本的 MSVC 2019 64-bit 组件。特别要注意 Qt 的编译器必须与 VS2019 匹配VS2019 对应 MSVC v142Qt 安装器里要选 “MSVC 2019 64-bit” 那一套不能选 MinGW 版本。我见过不少人在这一步翻车Qt 装的是 MinGW结果 VS2019 的 CMake 配置阶段就报 “Could NOT find Qt6”因为两者的 ABI 完全不兼容。3.2 CMake 配置核心命令与参数清单打开“x64 Native Tools Command Prompt for VS2019”开始菜单里搜这个名字先确认 CMake 和 Qt 的环境变量。然后进入源码目录执行以下命令mkdir build-vs2019 cd build-vs2019 cmake .. -G Visual Studio 16 2019 -A x64 ^ -DCMAKE_PREFIX_PATHC:/Qt/6.5.3/msvc2019_64 ^ -DCMAKE_BUILD_TYPERelease ^ -DCMAKE_INSTALL_PREFIXC:/kddockwidgets-install ^ -DKDDockWidgets_EXAMPLESON这里-G Visual Studio 16 2019指定生成 VS2019 工程-A x64指定 64 位架构如果你的目标平台是 x86可以改成 Win32但不建议Qt 官方发布的预编译库基本都是 64 位为主。CMAKE_PREFIX_PATH指向 Qt 的安装目录CMake 会在这里找 Qt6Config.cmake 之类的配置文件。KDDockWidgets_EXAMPLES打开示例工程建议第一次编译时打开编译完可以直接跑 examples 验证动态库是否正常。如果 CMake 报错找不到 Qt不要急着怀疑路径先检查C:/Qt/6.5.3/msvc2019_64/lib/cmake目录是否存在再确认 CMAKE_PREFIX_PATH 写的是否是这个路径的父目录。另外CMake 缓存会记住第一次配置的结果改路径后需要删掉 build 目录重来否则会继续用旧缓存报同样的错。3.3 编译与产物检查三个关键文件配置成功后执行编译命令。用 CMake 生成 VS 工程后也可以用 Visual Studio 直接打开 build-vs2019 目录下的 KDDockWidgets.sln在“解决方案配置”里切到 Release/x64右键 KDDockWidgets 项目选择“生成”。命令行方式更可控cmake --build . --config Release --parallel 8--config Release指定 Release 配置--parallel 8表示 8 线程并行编译第一次编译会比较久耐心等它跑完。编译完成后去build-vs2019/src/Release目录检查产物正常会有 KDDockWidgets.dll 和 KDDockWidgets.lib如果你用的是 Qt6还会见到 KDDockWidgets_Qt6.dll 这样带版本尾巴的库名。同时 examples/Release 下会有多个示例 exe随便挑一个运行比如最简单的 HelloWorld能看到窗口出现并且能拖动侧边栏就说明动态库本身没有问题。3.4 安装到本地省去手动拷 dll 的麻烦cmake --install . --config Release这条命令会把头文件、dll、lib、cmake 配置文件统一安装到 CMAKE_INSTALL_PREFIX 指定的目录。安装后的目录结构大概是这样include/KDDockWidgets 下是头文件bin 下是 dlllib 下是导入库lib/cmake 下是 KDDockWidgetsConfig.cmake。你后续自己的工程只要通过 find_package(KDDockWidgets) 就能接上不用再手动配置头文件路径和库路径。4. 把动态库接进你自己的 VS2019 Qt 工程两种链接方式4.1 隐式链接最常规的做法假设你自己有一个 Qt Widgets 工程工程文件是 .vcxproj。在项目属性里需要设置几个地方C/C → 常规 → 附加包含目录加上C:/kddockwidgets-install/include链接器 → 常规 → 附加库目录加上C:/kddockwidgets-install/lib链接器 → 输入 → 附加依赖项写上KDDockWidgets.libQt6 对应 KDDockWidgets_Qt6.lib。如果你用 CMake 管理自己的工程代码里只需要三行find_package(KDDockWidgets REQUIRED) target_link_libraries(your_app PRIVATE KDDockWidgets::kddockwidgets)这是最省心的方式KDDockWidgets 安装时已经导出了 CMake 的 package 配置find_package会把头文件目录、导入库、依赖的 Qt 模块一次性带全。注意你的工程里的 Qt 版本要和编译 KDDockWidgets 时用的一致混用 Qt5 编译的库和 Qt6 工程链接时会出现一堆 “unresolved external symbol”。4.2 使用 KDDockWidgets 的 API最小可运行代码动态库链接成功后写一段最小代码验证#include QApplication #include KDDockWidgets/MainWindow.h #include KDDockWidgets/DockWidget.h int main(int argc, char** argv) { QApplication app(argc, argv); KDDockWidgets::MainWindow window; window.resize(1024, 768); auto* dock new KDDockWidgets::DockWidget(Sidebar); dock-setWidget(new QTextEdit(window)); window.addDockWidgetAsTab(dock); window.show(); return app.exec(); }这段代码创建了一个主窗口把一个 DockWidget 以 Tab 页的形式加进去。addDockWidgetAsTab是最简单的停靠方式适合做第一个验证程序KDDockWidgets 还提供addDockWidgetAsSidePanel让面板停靠在侧边以及多个 DockWidget 之间的位置管理接口但先跑通这个最小例子比一上来就搞复杂布局稳妥得多。4.3 运行时找不到 dll 的排查顺序程序编译通过但运行时报 “无法启动此程序因为计算机中丢失 KDDockWidgets.dll”这是最常见的问题。排查顺序是第一把 KDDockWidgets.dll 拷贝到 exe 同目录第二确认 Qt 的 dllQt6Core.dll 等也在 exe 同目录或系统 PATH 里第三如果还报错用 Dependency Walker 或 Visual Studio 的“调试 → 窗口 → 模块”看具体缺哪个依赖。补充一点Qt 的插件如 platforms/qwindows.dll也要能被找到。如果你的 exe 目录下没有 platforms 文件夹Qt 程序启动时会直接崩溃这个和 KDDockWidgets 本身无关但经常被误认为是动态库有问题。用 windeployqt 工具可以自动把 Qt 运行库和插件拷贝到 exe 目录省去手工搬运。5. 动态库与源码的避坑清单五条血泪经验5.1 Debug 与 Release 混用导致的内存崩溃现象用 Release 版 KDDockWidgets.dll 链接 Debug 版自己的工程程序运行时随机崩溃有时是中文乱码有时是 QByteArray 内部断言失败。原因Qt 的 Debug 和 Release 使用不同的内存分配器和数据结构布局两个版本的 Qt 核心库混在一起时对象在 Release 库中创建、在 Debug 库中释放直接踩到堆损坏。解决KDDockWidgets 的库版本必须和你的工程一致。你的工程是 Debug 配置就必须用cmake --build . --config Debug编出来的 KDDockWidgetsd.dll注意名字里的 d。链接库也要对应Debug 工程链接 KDDockWidgetsd.libRelease 工程链接 KDDockWidgets.lib。5.2 源码更新后 dll 没重新编译界面出现“新接口找不到”现象刚拉取最新源码编译的 dll 替换到部署目录后程序启动报错找不到某个符号或者点击某功能时直接崩溃。原因KDDockWidgets 的源码更新频繁接口或类布局可能有变动旧 exe 链接的是旧版动态库导入表里的符号地址已经失效。解决本地源码更新后不要只编译 dll 替换要把自己工程的 exe 也重新编译一遍。如果你用隐式链接exe 和 dll 必须同时更新这是 Windows 动态链接的常识但在快速迭代时最容易疏忽。5.3 CMake 找不到 Qt但 Qt 明明装了现象CMake 配置时输出Could NOT find Qt6检查 Qt 路径确实存在。原因CMAKE_PREFIX_PATH 只给到了 Qt 的安装根目录但 CMake 需要的是C:/Qt/6.5.3/msvc2019_64这个包含 lib/cmake 的目录或者把 Qt 安装成了 MinGW 版本MSVC 的 CMake 工程找不到对应的配置。解决确认路径指向 Qt 对应编译器版本的根目录同时打开C:/Qt/6.5.3/msvc2019_64/lib/cmake看是否存在 Qt6Config.cmake 这一类文件。如果存在但 CMake 仍报错在 build 目录里删掉 CMakeCache.txt 重新配置不要复用旧缓存。5.4 编译成功但示例程序启动白屏现象KDDockWidgets 的 examples 编译通过运行后主窗口出现了但内容是空白的或者所有 DockWidget 都不显示。原因最常见的不是 KDDockWidgets 的问题而是 Qt 插件目录没有被识别。exe 在 build 目录下运行时Qt 找不到 platforms 插件。解决在 Qt 安装目录下找到C:/Qt/6.5.3/msvc2019_64/plugins/platforms把它整个拷贝到 exe 同目录下或者用 windeployqt 工具自动部署。之后再运行窗口内容就正常了。5.5 动态库文件拷贝不全部署到别的机器报错现象把 exe 和 KDDockWidgets.dll 拷到一台没装 Qt 的电脑上运行双击没反应事件查看器里显示找不到 Qt6Core.dll。原因KDDockWidgets.dll 依赖 Qt 运行库Qt 运行库又依赖 C 运行库单纯拷贝一个 dll 是不够的。解决不要手动挑 dll 拷贝用 Qt 自带的 windeployqt 命令。在 VS2019 的开发者命令行里执行windeployqt your_app.exe它会自动把 Qt 的 dll、插件、翻译文件全部拷到 exe 目录基本不会漏。6. 进阶用 KDDockWidgets 的调试日志验证动态库是否真的工作这个技巧对排查“dll 编好了但拖拽行为异常”特别有效。KDDockWidgets 内部预留了日志开关不需要改源码在程序启动前设置一个环境变量就能打开详细输出set KDDOCKWIDGETS_LOG_LEVELdebug然后在你的程序里加上一段代码把日志打印到控制台#include QDebug #include spdlog/spdlog.h int main(int argc, char** argv) { qputenv(KDDOCKWIDGETS_LOG_LEVEL, debug); spdlog::set_level(spdlog::level::debug); // 你的业务代码 }设置这个环境变量后KDDockWidgets 会输出拖拽事件、布局计算、窗口停靠的详细信息。比如拖一个 DockWidget 到边缘时日志里会显示DropArea::onDrop这样的关键字如果某次停靠失败日志里通常能看到Invalid drop position一类的提示。这个日志对确认“到底是动态库行为异常还是我的业务代码传参有误”非常有用。我自己的习惯是每次更新 KDDockWidgets 源码重新编译后先用 examples 跑一遍再打开日志跑一遍自己的工程最后才替换到正式分支。这样虽然多花几分钟但能提前过滤掉大部分“编译成功但运行行为不对”的坑。KDDockWidgets 这个库整体质量不错只要 Qt 版本、MSVC 工具集和 Debug/Release 这三组参数对齐VS2019 下编出可用的动态库并不难希望这些经验能帮你少走几步弯路。本文还有配套的精品资源点击获取