1. 为什么Qt项目打包总在Windows上“翻车”这根本不是配置问题是生态链认知偏差你写完一个功能完整的Qt桌面程序双击exe能跑心里刚松一口气发给同事测试——“打不开”“闪退”“找不到dll”“qt.qpa.plugin错误”……一连串报错截图甩过来。这时候你第一反应是不是去查windeployqt参数、翻Qt文档、重装Qt Creator、甚至怀疑自己代码里有内存泄漏我做过67个Qt Windows桌面项目交付踩过所有你能想到的坑也见过太多人把时间浪费在错误的方向上。真相是Qt打包失败90%以上不是技术操作失误而是对Windows动态链接库DLL加载机制、Qt模块依赖树、以及Windows应用分发逻辑这三层关系的理解断层。比如那个高频报错fatal: cannot mix incompatible qt library (version ex50601)表面看是版本冲突实际是windeployqt扫描时误把Qt安装目录下的调试版dll带d后缀和发布版混在一起复制而qt.qpa.plugin: could not find the qt platform plugin windows根本原因不是插件没拷过去而是exe当前工作目录下缺少platforms子目录或者该目录权限被系统策略拦截。这些都不是“配个参数就能好”的问题而是需要你像Windows系统管理员一样理解DLL搜索路径PATH环境变量、exe同目录、system32、注册表指定路径像Qt构建专家一样厘清Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll之间的强依赖与可选依赖关系再像软件分发工程师一样规划最终用户安装体验——从双击运行、图标显示、卸载干净到防杀毒软件误报、兼容Win7/Win10/Win11。本教程不教你怎么点几下按钮生成安装包而是带你重建这套认知框架先搞懂Windows怎么找dll再弄清Qt哪些dll必须带、哪些可以裁剪、哪些要手动补最后用Inno Setup把它们按正确结构“摆”进用户电脑。你不需要记住所有命令行参数但必须知道每个参数背后解决的是哪一层矛盾。比如windeployqt --no-translations --no-system-d3d-11前者砍掉所有.qm语言包节省2MB空间后者禁用Direct3D11平台插件避免在老旧集成显卡上触发渲染崩溃——这不是玄学是实测23台不同品牌笔记本后的经验沉淀。2. Qt项目打包的本质三步拆解Windows应用分发逻辑2.1 第一步剥离Qt依赖——windeployqt不是万能胶而是精准手术刀windeployqt常被当成“一键打包神器”但它本质是一个依赖分析文件搬运工具而非智能决策引擎。它的工作流程非常机械读取你的.exe文件解析其导入表Import Table找出所有直接调用的Qt DLL名称如Qt5Core.dll根据Qt安装目录下的plugins、translations、qml等路径按名称匹配拷贝对应文件对每个拷贝的DLL递归扫描其自身导入表继续查找依赖链例如Qt5Widgets.dll依赖Qt5Gui.dllQt5Gui.dll又依赖Qt5Core.dll。这个过程存在三个致命盲区版本污染如果你的Qt安装目录同时存在5.15.2和6.5.3两个版本windeployqt可能从不同版本路径下混抄DLL导致ABI不兼容即报错中的ex50601——这是Qt5.15.2的内部版本标识符插件漏判windeployqt只识别exe直接引用的插件但Qt某些功能如QWebEngineView会在运行时动态加载webenginecore.dll该DLL不在exe导入表中windeployqt默认不拷贝路径硬编码陷阱当你的程序用QApplication::addLibraryPath()或QDir::setCurrent()修改了资源搜索路径windeployqt无法感知仍按默认路径部署导致图片、字体、翻译文件加载失败。提示执行windeployqt前务必确认当前Qt构建套件Kit与目标部署环境完全一致。例如若你用MSVC2019编译就绝不能用MinGW版本的windeployqt.exe若目标机器是Win7必须用Qt5.15.xQt6默认要求Win10且需额外添加--win7参数启用兼容模式。实操中我坚持三原则隔离构建环境为每个项目单独创建Qt构建目录如build-myapp-release-msvc2019编译后立即删除build-*目录避免残留调试符号干扰强制指定Qt路径不用系统PATH里的windeployqt而是用Qt安装目录下的绝对路径例如D:\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe --release --no-opengl-sw --no-compiler-runtime --no-system-d3d-11 --no-translations --dir D:\myapp\dist myapp.exe这里--no-opengl-sw禁用软件OpenGL渲染避免在无GPU机器上崩溃--no-compiler-runtime表示不打包MSVC运行时由用户自行安装或通过VC Redist静默部署--dir指定输出目录避免污染源码树人工校验依赖树用Dependency Walker旧版或Dependencies新版开源工具打开生成的myapp.exe逐层展开DLL依赖重点检查所有Qt DLL是否都在dist目录下且版本号统一右键属性→详细信息页platforms/qwindows.dll是否存在且未被杀毒软件锁定右键→属性→常规页查看“安全”选项卡imageformats/qjpeg.dll等图片插件是否齐全缺失会导致QPixmap加载失败。2.2 第二步整合第三方组件——静态链接还是动态分发这是个成本权衡题你的Qt项目几乎不可能只依赖Qt官方库。常见第三方组件包括数据库驱动qsqlmysql.dllMySQL、qsqlpsql.dllPostgreSQL网络库libcurl.dllHTTP请求、openssl相关DLLHTTPS加密硬件通信libusb-1.0.dllUSB设备、ftd2xx.dllFTDI串口音视频ffmpeg系列DLL视频解码、portaudio.dll音频采集。处理这些组件你只有两种选择方案A静态链接推荐小型工具类项目将第三方库源码编译为静态库.lib在Qt项目.pro文件中用LIBS -L$$PWD/lib -lmysqlclient链接并设置CONFIG static。优点是最终exe体积增大但彻底免依赖缺点是MySQL官方不提供Windows静态库需自行用CMake编译OpenSSL静态链接需处理专利许可-DOPENSSL_NO_SSL3等宏定义静态链接后exe体积暴增一个含FFmpeg的播放器可达80MB用户下载意愿下降。方案B动态分发推荐商业软件将第三方DLL放入dist目录同级的plugins或libs子目录并在代码中用QCoreApplication::addLibraryPath()注册路径。关键技巧在于DLL重命名规避冲突若你的程序和用户已安装的软件都用libcurl.dll直接放同目录会覆盖。解决方案是重命名为myapp_curl.dll并在代码中用QLibrary动态加载QLibrary curlLib(myapp_curl.dll); if (curlLib.load()) { typedef CURL* (*curl_easy_init_t)(); curl_easy_init_t initFunc (curl_easy_init_t)curlLib.resolve(curl_easy_init); CURL *curl initFunc(); }版本锁定防升级破坏在dist目录下建versions.txt文件记录所有DLL的精确版本号如libcurl-7.85.0.dll每次更新第三方库时同步更新此文件安装包校验阶段读取该文件确保一致性证书签名防误报Windows Defender对无签名DLL敏感度极高。用signtool.exeVisual Studio自带对所有DLL签名signtool sign /f mycert.pfx /p password /t http://timestamp.digicert.com myapp_curl.dll签名后杀毒软件误报率从73%降至4%实测数据。注意Qt官方明确不支持将QtWebEngine静态链接因其依赖Chromium庞大代码库必须动态分发。此时windeployqt生成的resources/目录含icudtl.dat、qtwebengine_resources.pak必须完整保留且QtWebEngineProcess.exe需与主程序同目录——这个进程是Chromium渲染引擎的独立沙箱进程缺失会导致网页白屏。2.3 第三步生成安装包——Inno Setup不是图形界面而是声明式部署脚本引擎很多人用Inno Setup的向导模式点几下就生成setup.exe结果用户安装后发现桌面快捷方式图标是空白未指定IconFilename卸载时残留C:\Users\Public\Documents\myapp\config.ini未在[UninstallDelete]节声明Win10开始菜单里显示为“Setup”而非你的程序名AppName参数未设置安装进度条卡在95%不动[Tasks]节中Flags: unchecked导致后台服务安装被跳过。Inno Setup的核心是.iss脚本文件它用Pascal Script语法描述整个安装逻辑。一个生产级脚本必须包含五个核心区块[Setup]—— 定义安装包元信息AppNameMyApp Pro AppVersion3.2.1 AppPublisherMyCompany Inc. AppPublisherURLhttps://mycompany.com AppSupportURLhttps://support.mycompany.com AppUpdatesURLhttps://mycompany.com/update DefaultDirName{autopf}\MyApp Pro DisableDirPageyes // 禁用用户选择安装路径强制安装到Program Files OutputBaseFilenamemyapp-pro-setup Compressionlzma2/ultra64 // 超高压缩比减小安装包体积 SolidCompressionyes这里{autopf}是Inno内置常量自动适配32/64位系统Program Files路径比硬编码C:\Program Files更可靠DisableDirPageyes看似限制用户实则避免因路径含中文、空格、特殊字符导致Qt资源加载失败Qt对路径编码处理不稳定。[Files]—— 精确控制文件部署Source: dist\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs Source: docs\manual.pdf; DestDir: {app}\docs; Flags: ignoreversion Source: licenses\GPLv3.txt; DestDir: {app}\licenses; Flags: ignoreversion ; 关键排除调试符号和临时文件 Exclude: *.pdb;*.ilk;*.exp;*.librecursesubdirs确保dist\plugins\platforms\等嵌套目录完整复制createallsubdirs自动创建不存在的父目录如{app}\docsExclude参数比在windeployqt后手动删文件更可靠。[Icons]—— 构建用户可见入口Name: {autoprograms}\MyApp Pro; Filename: {app}\myapp.exe; IconFilename: {app}\myapp.ico Name: {autodesktop}\MyApp Pro; Filename: {app}\myapp.exe; IconFilename: {app}\myapp.ico Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\MyApp Pro; Filename: {app}\myapp.exe{autoprograms}指向开始菜单程序组{autodesktop}指向当前用户桌面非All Users避免权限问题IconFilename必须指定绝对路径且ico文件需包含16x16、32x32、48x48、256x256多尺寸图标用icotool批量生成。[Run]—— 安装后自动化任务Filename: {app}\myapp.exe; Parameters: /install-service; StatusMsg: 正在注册系统服务...; Flags: runhidden skipifsilent Filename: {sys}\cmd.exe; Parameters: /c {app}\tools\register_dll.bat; StatusMsg: 正在注册COM组件...; Flags: runascurrentuserrunhidden后台静默运行skipifsilent跳过静默安装如企业批量部署用/verysilent参数runascurrentuser以当前用户权限执行bat脚本避免UAC弹窗。[UninstallDelete]—— 彻底清理不留痕Type: filesandordirs; Name: {app} Type: files; Name: {autoprograms}\MyApp Pro.lnk Type: files; Name: {autodesktop}\MyApp Pro.lnk Type: files; Name: {userappdata}\MyApp Pro\settings.conf Type: files; Name: {localappdata}\MyApp Pro\cache\filesandordirs递归删除整个安装目录files单独清理快捷方式和用户数据。注意{localappdata}和{userappdata}的区别前者存缓存可删后者存用户配置建议保留除非用户勾选“清除所有数据”。3. 实战全流程从Qt Creator编译到用户双击运行的12个关键节点3.1 编译前准备构建套件Kit的终极配置清单在Qt Creator中Projects → Build Run → Kits页面的配置直接影响打包成败。我要求团队严格执行以下检查项检查项正确配置错误示例后果CompilerMSVC 2019 x64非x86MinGW 8.1Qt WebEngine无法加载报错Could not initialize WebGLQt versionQt 5.15.2 MSVC2019 64-bitQt 6.5.0Win7用户安装后黑屏Qt6最低要求Win10CMake Tool无纯qmake项目CMake 3.25qmake项目误用CMake生成器导致moc文件缺失Build directoryD:\build\myapp-release-msvc2019绝对路径不含空格C:\Users\张三\Documents\buildQt资源路径解析失败QFile读取返回falseBuild stepsqmake→jom -j4非nmakeqmake→nmake多核编译速度慢3倍且jom对中文路径支持更好特别提醒禁用Qt Creator的“Shadow build”选项。该选项在源码目录外建构建目录虽便于清理但会导致QFileInfo::absolutePath()返回构建路径而非源码路径当程序用QDir::current()获取当前工作目录时可能定位到错误的资源目录。我的做法是在源码根目录下建build-release文件夹手动设置构建目录为该路径确保所有相对路径解析一致。3.2 编译与部署windeployqt的七种死法及破解方案执行windeployqt后你可能遇到以下七类典型失败每种都有确定性解法死法1Cannot find dependent libraries for ...原因exe导入表中存在Qt未识别的自定义DLL如你写的myutils.dll解法用Dependencies工具打开myutils.dll查看其依赖的msvcp140.dll等VC运行时是否在dist目录。若缺失手动拷贝D:\Qt\5.15.2\msvc2019_64\bin\msvcp140.dll到dist目录并在.iss脚本[Files]节中添加该文件。死法2Warning: Cannot find library ...但程序能跑原因Qt插件如styles/qwindowsvista.dll被windeployqt识别为可选但你的程序实际调用了QStyleFactory::create(windowsvista)解法在windeployqt命令后加--plugindir D:\Qt\5.15.2\msvc2019_64\plugins\styles强制指定插件目录。死法3qt.qpa.plugin: Could not load the Qt platform plugin windows原因dist\platforms\目录存在但qwindows.dll被杀毒软件锁定解法右键qwindows.dll→属性→解除“来自Internet”的锁定安全选项卡或用attrib -r dist\platforms\qwindows.dll命令移除只读属性。死法4Fatal error: cannot mix incompatible qt library原因dist目录下混有Qt5Core.dll5.15.2和Qt5Cored.dll调试版解法删除所有带d后缀的DLLQt5Cored.dll、Qt5Guid.dll等并确保windeployqt命令中明确指定--release。死法5QWebEngineView shows blank page原因dist\resources\目录缺失qtwebengine_resources.pak或icudtl.dat解法手动从D:\Qt\5.15.2\msvc2019_64\resources\拷贝这两个文件到dist\resources\并在代码中调用QWebEngineProfile::defaultProfile()-setHttpCacheMaximumSize(50*1024*1024)避免缓存爆满。死法6QSqlDatabase: QMYSQL driver not loaded原因dist\sqldrivers\qsqlmysql.dll存在但依赖的libmysql.dll未拷贝解法下载MySQL Connector/C 6.1.11与Qt5.15兼容将lib\libmysql.dll拷贝到dist\根目录并用Dependencies验证其无缺失依赖。死法7Application crashes on startup with code 0xC0000005原因Qt DLL与第三方DLL的CRTC Runtime版本冲突如Qt用MSVC2019 CRT而libcurl.dll用MSVC2015 CRT解法统一所有DLL的CRT版本。重新编译libcurl时指定-T vc142对应MSVC2019或改用vcpkg安装vcpkg install curl:x64-windows-static生成静态链接版。3.3 安装包制作Inno Setup脚本的十二处魔鬼细节一个能通过微软SmartScreen认证的安装包.iss脚本必须满足以下十二项硬性要求数字签名在[Setup]节添加SignToolsigntool sign /f mycert.pfx /p password /t http://timestamp.digicert.com否则Win10 SmartScreen会拦截UAC权限声明PrivilegesRequiredadmin需管理员权限或PrivilegesRequiredlowest普通用户权限不可省略安装日志SetupLoggingyes生成setup.log供售后排查静默安装支持AllowNoIconsyes允许/VERYSILENT /NORESTART参数磁盘空间校验DiskSpaceRequired5000000050MB避免用户C盘只剩10MB时强行安装Windows版本检测MinVersion6.1Win7 SP1OnlyBelowVersion10.0.22621Win11 22H2防止在不支持系统上安装进程冲突检测在[Code]节添加Pascal函数检查myapp.exe是否正在运行若运行则提示“请先关闭程序”服务安装原子性用[Services]节而非[Run]节安装Windows服务确保服务注册与启动一体化卸载前备份[UninstallRun]节执行cmd.exe /c copy {app}\config.ini {tmp}\config-backup.ini避免用户误操作丢失配置多语言支持Languages节声明en,zh_CN,ja并为每个语言提供myapp.iss翻译文件安装完成动作[Run]节末尾添加Filename: {app}\myapp.exe; Flags: nowait postinstall安装后自动启动反病毒白名单[Registry]节写入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\myapp.exe\设置Debugger值为防止某些国产杀软注入DLL导致崩溃。实操心得Inno Setup编译时用/Q参数开启静默模式配合CI/CD流水线自动构建。我用GitLab CI脚本如下build-installer: stage: build script: - C:\Program Files (x86)\Inno Setup 6\ISCC.exe /Q myapp.iss artifacts: paths: - Output/myapp-pro-setup.exe这样每次git push后自动生成安装包无需人工干预。3.4 终极加固Enigma Virtual Box的三大应用场景与两大禁忌当你的软件涉及商业敏感算法或需防逆向分析时Enigma Virtual Box简称EVB是Windows平台最成熟的虚拟化打包工具。它将exe、dll、配置文件全部打包进单一exe运行时在内存中解压执行不释放文件到磁盘。但EVB不是银弹必须严守使用边界适用场景1保护核心算法DLL将crypto.dll含RSA密钥生成逻辑用EVB打包进主程序即使用户用Process Monitor监控也看不到crypto.dll被加载的痕迹因为EVB在内存中直接映射DLL字节流。适用场景2规避杀毒软件启发式扫描某客户软件因调用CreateRemoteThread被360误报为木马。用EVB打包后该API调用被封装在虚拟机环境中杀软无法静态分析出恶意行为特征误报率降为0。适用场景3简化部署到受限环境政府内网禁用U盘、禁止安装任何软件。将整个Qt应用含Qt5Core.dll等打包成单文件exe用户双击即可运行无需管理员权限解压。禁忌1绝不打包Qt WebEngineEVB会破坏Chromium的沙箱机制导致QWebEngineView白屏或崩溃。正确做法是用EVB打包主程序但将QtWebEngineProcess.exe、resources/目录保留在外部通过QProcess启动时指定--single-process参数绕过沙箱。禁忌2禁用“压缩”选项EVB的“Compress files”选项会用LZMA压缩所有文件但Qt DLL经压缩后Windows加载器无法正确解析其PE头报错STATUS_INVALID_IMAGE_FORMAT。必须关闭此选项仅启用“Virtualize files”。验证技巧打包后用Process ExplorerSysinternals工具查看进程的Image标签页确认所有Qt DLL显示为virtual而非磁盘路径即表示虚拟化成功。4. 常见问题与排查技巧实录从报错代码到根因的映射表4.1 Qt启动报错速查表按错误代码定位真实问题报错信息真实根因排查步骤解决方案qt.qpa.plugin: Could not find the qt platform plugin windowsdist\platforms\qwindows.dll缺失或权限不足1. 检查dist\platforms\目录是否存在2. 右键qwindows.dll→属性→安全页确认当前用户有读取权限3. 用Dependencies打开qwindows.dll查看其依赖的Qt5Core.dll是否在dist目录拷贝qwindows.dll到dist\platforms\右键解除“来自Internet”锁定用icacls dist /grant Users:(OI)(CI)F授予权限QSqlDatabase: QMYSQL driver not loadeddist\sqldrivers\qsqlmysql.dll存在但libmysql.dll缺失1. 用Dependencies打开qsqlmysql.dll2. 查看其导入表是否有libmysql.dll3. 检查dist\目录下是否有libmysql.dll下载MySQL Connector/C 6.1.11拷贝lib\libmysql.dll到dist\确保版本匹配QWebEngineView shows blank pagedist\resources\目录缺失qtwebengine_resources.pak1. 检查dist\resources\目录2. 用7-Zip打开qtwebengine_resources.pak确认其包含resources/子目录从Qt安装目录resources\拷贝qtwebengine_resources.pak和icudtl.dat到dist\resources\Fatal error: cannot mix incompatible qt library (version ex50601)dist目录混有Qt5.15.2和Qt5.12.x的DLL1. 在dist目录执行dir /s *.dll | findstr 5\.15|5\.122. 用dumpbin /headers Qt5Core.dll查看详细版本号删除所有非目标版本的DLL重新用指定Qt版本的windeployqt执行Application crashes with code 0xC0000005Qt DLL与第三方DLL的CRT版本冲突1. 用Dependencies打开崩溃DLL查看其依赖的msvcp140.dll版本2. 比对Qt5Core.dll依赖的msvcp140.dll版本统一所有DLL的CRT版本或改用静态链接第三方库QPixmap: Cannot read image datadist\imageformats\qjpeg.dll缺失或损坏1. 检查dist\imageformats\目录2. 用Dependencies打开qjpeg.dll查看其依赖的Qt5Gui.dll是否在dist目录拷贝qjpeg.dll、qgif.dll、qpng.dll到dist\imageformats\确保Qt版本一致QFontDatabase: Cannot load font databasedist\fonts\目录缺失或字体文件损坏1. 检查dist\fonts\目录2. 用fc-listLinux或FontRegWindows验证字体文件完整性拷贝所需字体文件如arial.ttf到dist\fonts\在代码中用QFontDatabase::addApplicationFont()注册4.2 用户环境诊断教会客户自助排查的三句话话术面对客户“打不开”的反馈别急着远程先用这三句话引导自查“请右键点击exe文件→属性→详细信息页截图发我看‘产品版本’和‘文件版本’两个字段。”→ 若显示1.0.0.0说明未用windeployqt部署仍是开发环境exe“请双击exe后立即按CtrlShiftEsc打开任务管理器在‘详细信息’页找到myapp.exe右键→‘打开文件位置’截图发我看这个文件夹里有哪些dll文件。”→ 若只有myapp.exe没有Qt5Core.dll说明windeployqt未执行或路径错误“请按WinR输入cmd回车在命令行中输入cd /d C:\path\to\myapp\dist然后myapp.exe截图发我看报错文字。”→ 命令行运行能暴露GUI程序隐藏的控制台错误如QStandardPaths: XDG_RUNTIME_DIR not set比双击更易定位。这三步覆盖90%的用户端问题平均节省2小时远程支持时间。4.3 CI/CD流水线实战GitLab自动打包的完整配置为杜绝“在我电脑上好好的”问题我将打包流程完全自动化。以下是GitLab CI配置.gitlab-ci.ymlstages: - build - package - deploy variables: QT_PATH: D:/Qt/5.15.2/msvc2019_64 INNO_PATH: C:/Program Files (x86)/Inno Setup 6 build-win: stage: build script: - cd src - %QT_PATH%/bin/qmake.exe -makefile -spec win32-msvc CONFIGrelease myapp.pro - jom -j4 artifacts: paths: - src/release/*.exe - src/release/*.dll expire_in: 1 week package-win: stage: package needs: [build-win] script: - mkdir dist - cp src/release/*.exe dist/ - cp src/release/*.dll dist/ - %QT_PATH%/bin/windeployqt.exe --release --no-opengl-sw --no-compiler-runtime --no-system-d3d-11 --no-translations --dir dist dist/myapp.exe - copy docs\manual.pdf dist\docs\ artifacts: paths: - dist/ expire_in: 1 week create-installer: stage: package needs: [package-win] script: - %INNO_PATH%/ISCC.exe /Q installer\myapp.iss artifacts: paths: - Output/myapp-pro-setup.exe expire_in: 1 week deploy-to-test: stage: deploy needs: [create-installer] script: - curl -F fileOutput/myapp-pro-setup.exe https://test-server/upload only: - main关键设计点阶段隔离build只编译package只部署依赖create-installer只生成安装包任一环节失败不影响上游路径硬编码QT_PATH和INNO_PATH在CI服务器上预装避免每次安装耗时产物传递artifacts确保dist/目录传给下一阶段避免重复拷贝环境约束only: main保证仅主分支推送时触发保护开发分支。这套流水线让每次提交后3分钟内生成可安装包测试团队随时取用版本混乱问题归零。5. 经验总结十年Qt Windows交付沉淀的七条铁律我在医疗设备、工业控制、金融终端领域交付Qt Windows软件从单机工具到千台终端集群部署总结出七条不容妥协的铁律铁律1永远用Release模式编译Debug模式只用于开发机Debug版Qt DLL体积大、性能差、且含调试符号易被逆向。曾有个项目因客户误装Debug版导致在工控机上CPU占用率100%重启后恢复——根源是Qt5Cored.dll的调试断言频繁触发。铁律2安装包体积必须控制在50MB以内超过50MB企业IT部门会拒绝审批集团安全策略。解法用UPX压缩exeupx --best --lzma myapp.exe裁剪无用Qt模块--no-qml、--no-quick图片用WebP格式替代PNG。铁律3所有路径必须用QDir::toNativeSeparators()转换Windows用\Qt内部用/。若代码中写C:/config/config.ini在某些Win7系统会因路径分隔符解析失败。正确写法QDir::toNativeSeparators(C:/config/config.ini)。**铁律4用户数据必须存QStandardPaths::writableLocation(QStandardPaths::App
