635 lines
13 KiB
Markdown
635 lines
13 KiB
Markdown
# Qt6 应用程序部署指南
|
||
|
||
本指南详细说明如何将 Qt6 GUI 应用程序(`agv_qt_gui.exe`)部署到其他计算机,使其能够独立运行而无需安装 Qt。
|
||
|
||
## 📋 目录
|
||
- [部署方法概述](#部署方法概述)
|
||
- [方法 1: 使用 windeployqt(推荐)](#方法-1-使用-windeployqt推荐)
|
||
- [方法 2: 手动复制依赖](#方法-2-手动复制依赖)
|
||
- [方法 3: 静态链接](#方法-3-静态链接)
|
||
- [Linux 部署](#linux-部署)
|
||
- [测试部署包](#测试部署包)
|
||
- [常见问题](#常见问题)
|
||
|
||
---
|
||
|
||
## 部署方法概述
|
||
|
||
Qt 应用程序部署有三种主要方法:
|
||
|
||
| 方法 | 优点 | 缺点 | 适用场景 |
|
||
|------|------|------|---------|
|
||
| **windeployqt** | 自动、快速、简单 | 包体积较大(~50MB) | 推荐,适合大多数情况 |
|
||
| **手动复制** | 精确控制,体积可优化 | 需要手动查找依赖 | 高级用户,需要精简包 |
|
||
| **静态链接** | 单一可执行文件,最小依赖 | 编译慢,体积大(~30MB) | 商业发布 |
|
||
|
||
---
|
||
|
||
## 方法 1: 使用 windeployqt(推荐)
|
||
|
||
`windeployqt` 是 Qt 官方提供的部署工具,可自动收集所有必需的 DLL、插件和资源。
|
||
|
||
### Windows (MinGW) 部署
|
||
|
||
#### 步骤 1: 创建部署目录
|
||
|
||
```bash
|
||
# 在项目根目录下创建发布目录
|
||
mkdir -p release_package
|
||
cd release_package
|
||
```
|
||
|
||
#### 步骤 2: 复制可执行文件
|
||
|
||
```bash
|
||
# 复制编译好的 exe
|
||
cp ../build/agv_qt_gui.exe .
|
||
|
||
# 复制必需的数据文件(如果有)
|
||
# cp -r ../data .
|
||
# cp -r ../config .
|
||
```
|
||
|
||
#### 步骤 3: 运行 windeployqt
|
||
|
||
```bash
|
||
# 添加 Qt bin 目录到 PATH(临时)
|
||
export PATH=/c/Qt/6.10.1/mingw_64/bin:$PATH
|
||
|
||
# 运行 windeployqt
|
||
windeployqt agv_qt_gui.exe
|
||
|
||
# 或者使用完整路径
|
||
/c/Qt/6.10.1/mingw_64/bin/windeployqt.exe agv_qt_gui.exe
|
||
```
|
||
|
||
**参数说明:**
|
||
```bash
|
||
# 基本部署
|
||
windeployqt agv_qt_gui.exe
|
||
|
||
# Release 模式(不包含调试信息)
|
||
windeployqt --release agv_qt_gui.exe
|
||
|
||
# 指定编译器
|
||
windeployqt --compiler-runtime agv_qt_gui.exe
|
||
|
||
# 显示详细信息
|
||
windeployqt --verbose 2 agv_qt_gui.exe
|
||
|
||
# 不复制编译器运行时
|
||
windeployqt --no-compiler-runtime agv_qt_gui.exe
|
||
```
|
||
|
||
#### 步骤 4: 添加 MinGW 运行时(如需要)
|
||
|
||
```bash
|
||
# 复制 MinGW 运行时 DLL
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libgcc_s_seh-1.dll .
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libstdc++-6.dll .
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libwinpthread-1.dll .
|
||
```
|
||
|
||
#### 步骤 5: 复制 ControlCAN 库(AGV 特定)
|
||
|
||
```bash
|
||
# 复制 CAN 通信库
|
||
cp ../lib/ControlCAN.dll . # 如果存在 DLL 版本
|
||
```
|
||
|
||
#### 步骤 6: 创建启动脚本(可选)
|
||
|
||
创建 `run.bat`:
|
||
```batch
|
||
@echo off
|
||
echo Starting AGV Path Tracking GUI...
|
||
agv_qt_gui.exe
|
||
if errorlevel 1 (
|
||
echo Program exited with error code %errorlevel%
|
||
pause
|
||
)
|
||
```
|
||
|
||
#### 完整自动化脚本
|
||
|
||
创建 `deploy_windows.sh`:
|
||
```bash
|
||
#!/bin/bash
|
||
|
||
# Qt6 部署脚本 for Windows MinGW
|
||
|
||
# 配置
|
||
QT_DIR="/c/Qt/6.10.1/mingw_64"
|
||
MINGW_DIR="/c/Qt/Tools/mingw1310_64"
|
||
BUILD_DIR="../build"
|
||
DEPLOY_DIR="release_package"
|
||
EXE_NAME="agv_qt_gui.exe"
|
||
|
||
echo "=== AGV Qt6 GUI 部署脚本 ==="
|
||
|
||
# 1. 创建部署目录
|
||
echo "[1/6] 创建部署目录..."
|
||
rm -rf "$DEPLOY_DIR"
|
||
mkdir -p "$DEPLOY_DIR"
|
||
|
||
# 2. 复制可执行文件
|
||
echo "[2/6] 复制可执行文件..."
|
||
if [ ! -f "$BUILD_DIR/$EXE_NAME" ]; then
|
||
echo "错误: 找不到 $BUILD_DIR/$EXE_NAME"
|
||
echo "请先编译项目!"
|
||
exit 1
|
||
fi
|
||
cp "$BUILD_DIR/$EXE_NAME" "$DEPLOY_DIR/"
|
||
|
||
# 3. 运行 windeployqt
|
||
echo "[3/6] 运行 windeployqt..."
|
||
cd "$DEPLOY_DIR"
|
||
"$QT_DIR/bin/windeployqt.exe" --release --no-translations "$EXE_NAME"
|
||
|
||
# 4. 复制 MinGW 运行时
|
||
echo "[4/6] 复制 MinGW 运行时..."
|
||
cp "$MINGW_DIR/bin/libgcc_s_seh-1.dll" .
|
||
cp "$MINGW_DIR/bin/libstdc++-6.dll" .
|
||
cp "$MINGW_DIR/bin/libwinpthread-1.dll" .
|
||
|
||
# 5. 复制 CAN 库(如果存在)
|
||
echo "[5/6] 复制 CAN 库..."
|
||
if [ -f "../lib/ControlCAN.dll" ]; then
|
||
cp "../lib/ControlCAN.dll" .
|
||
fi
|
||
|
||
# 6. 创建启动脚本
|
||
echo "[6/6] 创建启动脚本..."
|
||
cat > run.bat << 'EOF'
|
||
@echo off
|
||
echo ========================================
|
||
echo AGV Path Tracking Control System
|
||
echo Qt6 GUI Application
|
||
echo ========================================
|
||
echo.
|
||
agv_qt_gui.exe
|
||
if errorlevel 1 (
|
||
echo.
|
||
echo Program exited with error code %errorlevel%
|
||
pause
|
||
)
|
||
EOF
|
||
|
||
cd ..
|
||
|
||
# 显示结果
|
||
echo ""
|
||
echo "=== 部署完成! ==="
|
||
echo "部署目录: $DEPLOY_DIR"
|
||
echo "可执行文件: $EXE_NAME"
|
||
echo ""
|
||
echo "目录内容:"
|
||
ls -lh "$DEPLOY_DIR" | head -20
|
||
|
||
# 计算大小
|
||
TOTAL_SIZE=$(du -sh "$DEPLOY_DIR" | cut -f1)
|
||
echo ""
|
||
echo "总大小: $TOTAL_SIZE"
|
||
echo ""
|
||
echo "现在可以将 '$DEPLOY_DIR' 文件夹复制到其他计算机运行!"
|
||
```
|
||
|
||
使用部署脚本:
|
||
```bash
|
||
chmod +x deploy_windows.sh
|
||
./deploy_windows.sh
|
||
```
|
||
|
||
---
|
||
|
||
### Windows (MSVC) 部署
|
||
|
||
与 MinGW 类似,但需要使用 MSVC 版本的 Qt 和运行时:
|
||
|
||
```bash
|
||
# 使用 MSVC 版 Qt
|
||
C:\Qt\6.10.1\msvc2019_64\bin\windeployqt.exe --release agv_qt_gui.exe
|
||
|
||
# MSVC 运行时通常由 windeployqt 自动包含
|
||
# 如果没有,需要安装 Visual C++ Redistributable
|
||
```
|
||
|
||
---
|
||
|
||
## 方法 2: 手动复制依赖
|
||
|
||
如果需要精确控制部署内容或 `windeployqt` 不可用:
|
||
|
||
### 步骤 1: 确定依赖的 DLL
|
||
|
||
使用 `ldd` 或 `depends.exe` 查看依赖:
|
||
|
||
```bash
|
||
# 使用 ldd (Git Bash / MSYS2)
|
||
ldd build/agv_qt_gui.exe
|
||
|
||
# 输出示例:
|
||
# Qt6Core.dll
|
||
# Qt6Gui.dll
|
||
# Qt6Widgets.dll
|
||
# libgcc_s_seh-1.dll
|
||
# libstdc++-6.dll
|
||
# libwinpthread-1.dll
|
||
```
|
||
|
||
### 步骤 2: 复制核心 Qt DLL
|
||
|
||
```bash
|
||
cd release_package
|
||
|
||
# Qt6 核心库
|
||
cp /c/Qt/6.10.1/mingw_64/bin/Qt6Core.dll .
|
||
cp /c/Qt/6.10.1/mingw_64/bin/Qt6Gui.dll .
|
||
cp /c/Qt/6.10.1/mingw_64/bin/Qt6Widgets.dll .
|
||
```
|
||
|
||
### 步骤 3: 复制平台插件
|
||
|
||
```bash
|
||
# 创建 platforms 目录
|
||
mkdir -p platforms
|
||
|
||
# 复制 Windows 平台插件
|
||
cp /c/Qt/6.10.1/mingw_64/plugins/platforms/qwindows.dll platforms/
|
||
```
|
||
|
||
### 步骤 4: 复制样式插件(可选)
|
||
|
||
```bash
|
||
# 创建 styles 目录
|
||
mkdir -p styles
|
||
|
||
# 复制 Windows 样式
|
||
cp /c/Qt/6.10.1/mingw_64/plugins/styles/qwindowsvistastyle.dll styles/
|
||
```
|
||
|
||
### 步骤 5: 复制编译器运行时
|
||
|
||
```bash
|
||
# MinGW 运行时
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libgcc_s_seh-1.dll .
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libstdc++-6.dll .
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libwinpthread-1.dll .
|
||
```
|
||
|
||
### 最小部署结构
|
||
|
||
```
|
||
release_package/
|
||
├── agv_qt_gui.exe # 主程序
|
||
├── Qt6Core.dll # Qt 核心
|
||
├── Qt6Gui.dll # Qt GUI
|
||
├── Qt6Widgets.dll # Qt Widgets
|
||
├── libgcc_s_seh-1.dll # GCC 运行时
|
||
├── libstdc++-6.dll # C++ 标准库
|
||
├── libwinpthread-1.dll # 线程库
|
||
├── ControlCAN.dll # CAN 通信库(如需要)
|
||
└── platforms/ # 平台插件目录
|
||
└── qwindows.dll # Windows 平台插件
|
||
```
|
||
|
||
---
|
||
|
||
## 方法 3: 静态链接
|
||
|
||
静态链接将所有依赖编译进可执行文件,生成单一的 exe(但需要静态版 Qt)。
|
||
|
||
### 前提条件
|
||
|
||
- 需要从源码编译静态版 Qt6(耗时较长)
|
||
- 或者购买商业版 Qt(包含静态库)
|
||
|
||
### 编译静态 Qt6
|
||
|
||
```bash
|
||
# 下载 Qt 源码
|
||
git clone https://code.qt.io/qt/qt5.git qt6-static
|
||
cd qt6-static
|
||
git checkout 6.10.1
|
||
|
||
# 配置静态编译
|
||
./configure -static -prefix C:/Qt/6.10.1-static -release -nomake examples -nomake tests
|
||
|
||
# 编译(需要数小时)
|
||
cmake --build . --parallel
|
||
cmake --install .
|
||
```
|
||
|
||
### 使用静态 Qt 编译项目
|
||
|
||
```bash
|
||
cd build
|
||
cmake -DCMAKE_PREFIX_PATH=C:/Qt/6.10.1-static ..
|
||
cmake --build . --config Release
|
||
```
|
||
|
||
静态编译的 exe 大约 30-50MB,但不需要任何 DLL。
|
||
|
||
---
|
||
|
||
## Linux 部署
|
||
|
||
### 使用系统包管理器(推荐)
|
||
|
||
```bash
|
||
# Ubuntu/Debian
|
||
sudo apt install qt6-base-dev
|
||
|
||
# 用户安装后从包管理器安装 Qt6 即可运行
|
||
```
|
||
|
||
### 使用 AppImage(便携)
|
||
|
||
创建 AppImage 可部署到任何 Linux 发行版:
|
||
|
||
```bash
|
||
# 安装 linuxdeployqt
|
||
wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
|
||
chmod +x linuxdeployqt-continuous-x86_64.AppImage
|
||
|
||
# 准备 AppDir
|
||
mkdir -p AppDir/usr/bin
|
||
cp build/agv_qt_gui AppDir/usr/bin/
|
||
|
||
# 创建 desktop 文件
|
||
cat > AppDir/agv_qt_gui.desktop << EOF
|
||
[Desktop Entry]
|
||
Type=Application
|
||
Name=AGV Path Tracking
|
||
Exec=agv_qt_gui
|
||
Icon=agv_icon
|
||
Categories=Development;
|
||
EOF
|
||
|
||
# 运行 linuxdeployqt
|
||
./linuxdeployqt-continuous-x86_64.AppImage AppDir/usr/bin/agv_qt_gui -appimage
|
||
|
||
# 生成 agv_qt_gui-x86_64.AppImage
|
||
```
|
||
|
||
---
|
||
|
||
## 测试部署包
|
||
|
||
### 在干净环境中测试
|
||
|
||
**方法 1: 使用虚拟机**
|
||
- 创建 Windows 虚拟机(VirtualBox / VMware)
|
||
- 不安装 Qt 和 MinGW
|
||
- 复制 `release_package` 文件夹
|
||
- 运行 `agv_qt_gui.exe`
|
||
|
||
**方法 2: 使用其他电脑**
|
||
- 找一台没有安装 Qt 的电脑
|
||
- 复制部署包
|
||
- 双击运行
|
||
|
||
**方法 3: 临时重命名 Qt 目录**
|
||
```bash
|
||
# 重命名 Qt 目录(临时测试)
|
||
mv /c/Qt /c/Qt_backup
|
||
|
||
# 测试部署的程序
|
||
cd release_package
|
||
./agv_qt_gui.exe
|
||
|
||
# 测试完成后恢复
|
||
mv /c/Qt_backup /c/Qt
|
||
```
|
||
|
||
### 检查清单
|
||
|
||
- [ ] 程序能正常启动
|
||
- [ ] 主窗口正常显示
|
||
- [ ] 所有控件可交互
|
||
- [ ] 路径生成功能正常
|
||
- [ ] CSV 文件加载正常
|
||
- [ ] 动画播放正常
|
||
- [ ] 没有"缺少 DLL"错误
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### 问题 1: 启动时报错"缺少 Qt6Core.dll"
|
||
|
||
**原因:** Qt 核心库未包含
|
||
|
||
**解决方案:**
|
||
```bash
|
||
# 重新运行 windeployqt
|
||
cd release_package
|
||
/c/Qt/6.10.1/mingw_64/bin/windeployqt.exe agv_qt_gui.exe
|
||
|
||
# 或手动复制
|
||
cp /c/Qt/6.10.1/mingw_64/bin/Qt6Core.dll .
|
||
```
|
||
|
||
---
|
||
|
||
### 问题 2: 启动时报错"找不到平台插件 'windows'"
|
||
|
||
**原因:** 缺少平台插件
|
||
|
||
**解决方案:**
|
||
```bash
|
||
mkdir -p platforms
|
||
cp /c/Qt/6.10.1/mingw_64/plugins/platforms/qwindows.dll platforms/
|
||
```
|
||
|
||
---
|
||
|
||
### 问题 3: 程序启动后立即崩溃
|
||
|
||
**原因:** 缺少 MinGW 运行时或编译器不匹配
|
||
|
||
**解决方案:**
|
||
```bash
|
||
# 复制 MinGW 运行时
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libgcc_s_seh-1.dll .
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libstdc++-6.dll .
|
||
cp /c/Qt/Tools/mingw1310_64/bin/libwinpthread-1.dll .
|
||
```
|
||
|
||
---
|
||
|
||
### 问题 4: 部署包过大(>100MB)
|
||
|
||
**原因:** windeployqt 包含了不必要的文件
|
||
|
||
**优化方案:**
|
||
```bash
|
||
# 使用精简选项
|
||
windeployqt --release --no-translations --no-system-d3d-compiler agv_qt_gui.exe
|
||
|
||
# 删除不需要的插件
|
||
rm -rf iconengines imageformats/qtiff.dll imageformats/qwebp.dll
|
||
|
||
# 删除调试符号
|
||
find . -name "*.pdb" -delete
|
||
```
|
||
|
||
---
|
||
|
||
### 问题 5: 中文路径显示乱码
|
||
|
||
**原因:** 缺少字体或编码设置
|
||
|
||
**解决方案:**
|
||
```bash
|
||
# 确保使用 UTF-8 编码
|
||
# 在程序开始时添加:
|
||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||
```
|
||
|
||
---
|
||
|
||
## 部署包优化
|
||
|
||
### 减小体积
|
||
|
||
```bash
|
||
# 1. 删除不需要的翻译文件
|
||
rm -rf translations
|
||
|
||
# 2. 删除不需要的图像格式插件
|
||
cd imageformats
|
||
rm -f qicns.dll qico.dll qtga.dll qtiff.dll qwbmp.dll qwebp.dll
|
||
cd ..
|
||
|
||
# 3. 使用 UPX 压缩(可选)
|
||
upx --best agv_qt_gui.exe
|
||
upx --best *.dll
|
||
```
|
||
|
||
### 创建安装程序
|
||
|
||
使用 NSIS 或 Inno Setup 创建安装程序:
|
||
|
||
**Inno Setup 示例脚本 (deploy.iss):**
|
||
```ini
|
||
[Setup]
|
||
AppName=AGV Path Tracking
|
||
AppVersion=1.0
|
||
DefaultDirName={pf}\AGV Path Tracking
|
||
DefaultGroupName=AGV Tools
|
||
OutputDir=installer
|
||
OutputBaseFilename=AGV_PathTracking_Setup
|
||
|
||
[Files]
|
||
Source: "release_package\*"; DestDir: "{app}"; Flags: recursesubdirs
|
||
|
||
[Icons]
|
||
Name: "{group}\AGV Path Tracking"; Filename: "{app}\agv_qt_gui.exe"
|
||
Name: "{commondesktop}\AGV Path Tracking"; Filename: "{app}\agv_qt_gui.exe"
|
||
```
|
||
|
||
编译安装程序:
|
||
```bash
|
||
iscc deploy.iss
|
||
```
|
||
|
||
---
|
||
|
||
## 部署检查脚本
|
||
|
||
创建 `check_deployment.sh`:
|
||
```bash
|
||
#!/bin/bash
|
||
|
||
DEPLOY_DIR="release_package"
|
||
EXE="agv_qt_gui.exe"
|
||
|
||
echo "=== AGV Qt6 部署检查 ==="
|
||
echo ""
|
||
|
||
# 1. 检查可执行文件
|
||
if [ -f "$DEPLOY_DIR/$EXE" ]; then
|
||
echo "✓ 可执行文件存在"
|
||
else
|
||
echo "✗ 缺少可执行文件"
|
||
exit 1
|
||
fi
|
||
|
||
# 2. 检查必需的 DLL
|
||
REQUIRED_DLLS=(
|
||
"Qt6Core.dll"
|
||
"Qt6Gui.dll"
|
||
"Qt6Widgets.dll"
|
||
"libgcc_s_seh-1.dll"
|
||
"libstdc++-6.dll"
|
||
"libwinpthread-1.dll"
|
||
)
|
||
|
||
cd "$DEPLOY_DIR"
|
||
for dll in "${REQUIRED_DLLS[@]}"; do
|
||
if [ -f "$dll" ]; then
|
||
echo "✓ $dll"
|
||
else
|
||
echo "✗ 缺少 $dll"
|
||
fi
|
||
done
|
||
|
||
# 3. 检查平台插件
|
||
if [ -f "platforms/qwindows.dll" ]; then
|
||
echo "✓ platforms/qwindows.dll"
|
||
else
|
||
echo "✗ 缺少 platforms/qwindows.dll"
|
||
fi
|
||
|
||
# 4. 计算总大小
|
||
echo ""
|
||
echo "部署包大小:"
|
||
du -sh .
|
||
|
||
# 5. 列出所有 DLL
|
||
echo ""
|
||
echo "包含的 DLL 文件:"
|
||
find . -name "*.dll" | wc -l
|
||
echo "个文件"
|
||
|
||
cd ..
|
||
echo ""
|
||
echo "检查完成!"
|
||
```
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
### 推荐的部署流程
|
||
|
||
1. **开发阶段**: 使用完整 Qt 开发环境
|
||
2. **测试阶段**: 使用 `windeployqt` 创建部署包
|
||
3. **发布阶段**: 优化部署包,创建安装程序
|
||
|
||
### 部署清单
|
||
|
||
- [ ] 编译 Release 版本
|
||
- [ ] 运行 `windeployqt`
|
||
- [ ] 复制 MinGW 运行时
|
||
- [ ] 复制项目特定依赖(ControlCAN.dll)
|
||
- [ ] 在干净环境测试
|
||
- [ ] 优化体积
|
||
- [ ] 创建安装程序(可选)
|
||
- [ ] 编写用户手册
|
||
|
||
---
|
||
|
||
## 相关资源
|
||
|
||
- **Qt 官方文档**: [Deploying Qt Applications](https://doc.qt.io/qt-6/deployment.html)
|
||
- **windeployqt 文档**: [Qt for Windows - Deployment](https://doc.qt.io/qt-6/windows-deployment.html)
|
||
- **依赖检查工具**: [Dependency Walker](http://www.dependencywalker.com/)
|
||
|
||
---
|
||
|
||
**最后更新:** 2025-11-27
|
||
**Qt 版本:** 6.10.1
|
||
**平台:** Windows MinGW, Windows MSVC, Linux
|