Qt文件压缩工具项目开发教程

Qt文件压缩工具项目开发教程

项目概述

本项目是一个基于Qt 5.9.9开发的文件压缩工具,具有现代化的用户界面和强大的功能特性。该工具支持多种压缩格式(ZIP、GZIP),提供文件压缩、解压缩、批量处理等功能,是一个完整的桌面应用程序开发案例。

主要特性

  • 多格式支持:ZIP、GZIP压缩格式
  • 批量处理:支持多文件和文件夹同时压缩
  • 拖拽操作:支持文件拖拽到界面
  • 进度显示:实时显示压缩/解压进度
  • 多线程处理:后台处理,不阻塞界面
  • 现代化UI:美观的用户界面设计

技术栈

  • 开发框架:Qt 5.9.9
  • 编译器:MinGW32
  • 开发语言:C++
  • 界面设计:Qt Widgets + .ui文件
  • 多线程:QThread + QObject
  • 压缩库:zlib

项目结构

复制代码
18_FileCompressionTool/
├── 18_FileCompressionTool.pro    # Qt项目文件
├── main.cpp                      # 程序入口
├── mainwindow.h                  # 主窗口头文件
├── mainwindow.cpp                # 主窗口实现
├── mainwindow.ui                 # UI界面文件
├── compressionworker.h           # 压缩工作线程头文件
├── compressionworker.cpp         # 压缩工作线程实现
└── README.md                     # 项目说明

源代码下载链接https://download.csdn.net/download/weixin_42059464/91725199

核心功能实现

1. 界面设计

主窗口采用分组布局设计,包含文件列表、压缩设置、操作按钮和进度显示四个主要区域。

cpp 复制代码
// mainwindow.h - 界面组件定义
class MainWindow : public QMainWindow
{
private:
    // 文件列表区域
    QGroupBox *fileGroupBox;
    QListWidget *fileListWidget;
    QPushButton *addFilesButton;
    QPushButton *addFolderButton;
    QPushButton *removeFilesButton;
    QPushButton *clearFilesButton;
    
    // 压缩设置区域
    QGroupBox *settingsGroupBox;
    QComboBox *formatComboBox;
    QComboBox *levelComboBox;
    QLineEdit *outputPathEdit;
    QPushButton *browseOutputButton;
    
    // 操作区域
    QGroupBox *operationGroupBox;
    QPushButton *compressButton;
    QPushButton *extractButton;
    
    // 进度区域
    QGroupBox *progressGroupBox;
    QProgressBar *progressBar;
    QLabel *statusLabel;
};

界面初始化代码:

cpp 复制代码
// mainwindow.cpp - 界面设置
void MainWindow::setupUI()
{
    // 创建中央部件和主布局
    centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    
    mainLayout = new QVBoxLayout(centralWidget);
    mainLayout->setSpacing(10);
    mainLayout->setContentsMargins(10, 10, 10, 10);
    
    // 文件列表区域
    fileGroupBox = new QGroupBox("文件列表", centralWidget);
    QVBoxLayout *fileLayout = new QVBoxLayout(fileGroupBox);
    
    fileListWidget = new QListWidget(fileGroupBox);
    fileListWidget->setMinimumHeight(150);
    fileListWidget->setAcceptDrops(true);
    fileListWidget->setDragEnabled(true);
    fileListWidget->setDragDropMode(QAbstractItemView::DragDrop);
    
    // 添加按钮布局
    fileButtonLayout = new QHBoxLayout();
    addFilesButton = new QPushButton("添加文件", fileGroupBox);
    addFolderButton = new QPushButton("添加文件夹", fileGroupBox);
    removeFilesButton = new QPushButton("移除文件", fileGroupBox);
    clearFilesButton = new QPushButton("清空列表", fileGroupBox);
    
    fileButtonLayout->addWidget(addFilesButton);
    fileButtonLayout->addWidget(addFolderButton);
    fileButtonLayout->addWidget(removeFilesButton);
    fileButtonLayout->addWidget(clearFilesButton);
    fileButtonLayout->addStretch();
}

2. 信号槽机制

项目采用Qt的信号槽机制实现组件间的通信,确保界面响应性和数据一致性。

cpp 复制代码
// mainwindow.cpp - 信号槽连接
void MainWindow::setupConnections()
{
    // 文件操作信号槽
    connect(addFilesButton, &QPushButton::clicked, 
            this, &MainWindow::onAddFilesClicked);
    connect(addFolderButton, &QPushButton::clicked, 
            this, &MainWindow::onAddFolderClicked);
    connect(removeFilesButton, &QPushButton::clicked, 
            this, &MainWindow::onRemoveFilesClicked);
    connect(clearFilesButton, &QPushButton::clicked, 
            this, &MainWindow::onClearFilesClicked);
    
    // 压缩操作信号槽
    connect(compressButton, &QPushButton::clicked, 
            this, &MainWindow::onCompressClicked);
    connect(extractButton, &QPushButton::clicked, 
            this, &MainWindow::onExtractClicked);
    connect(browseOutputButton, &QPushButton::clicked, 
            this, &MainWindow::onBrowseOutputClicked);
    
    // 工作线程信号槽
    connect(compressionWorker, &CompressionWorker::compressionProgress,
            this, &MainWindow::onCompressionProgress);
    connect(compressionWorker, &CompressionWorker::compressionFinished,
            this, &MainWindow::onCompressionFinished);
    connect(compressionWorker, &CompressionWorker::extractionProgress,
            this, &MainWindow::onExtractionProgress);
    connect(compressionWorker, &CompressionWorker::extractionFinished,
            this, &MainWindow::onExtractionFinished);
}

3. 多线程处理

使用QThread和QObject实现后台压缩处理,避免界面阻塞。

cpp 复制代码
// compressionworker.h - 工作线程定义
class CompressionWorker : public QObject
{
    Q_OBJECT

public:
    enum CompressionFormat {
        ZIP,
        GZIP,
        BZIP2
    };

    enum CompressionLevel {
        FAST = 1,
        NORMAL = 5,
        MAXIMUM = 9
    };

public slots:
    void compressFiles(const QStringList &fileList, 
                      const QString &outputPath,
                      CompressionFormat format = ZIP,
                      CompressionLevel level = NORMAL);
    void extractFile(const QString &archivePath, 
                    const QString &outputPath);
    void cancelOperation();

signals:
    void compressionProgress(int percentage);
    void compressionFinished(bool success, const QString &message);
    void extractionProgress(int percentage);
    void extractionFinished(bool success, const QString &message);
};

线程创建和管理:

cpp 复制代码
// mainwindow.cpp - 线程管理
void MainWindow::onCompressClicked()
{
    if (fileList.isEmpty()) {
        QMessageBox::warning(this, "警告", "请先添加要压缩的文件");
        return;
    }
    
    // 创建工作线程
    compressionWorker = new CompressionWorker();
    workerThread = new QThread();
    compressionWorker->moveToThread(workerThread);
    
    // 连接信号槽
    connect(workerThread, &QThread::started, [this]() {
        CompressionWorker::CompressionFormat format = 
            static_cast<CompressionWorker::CompressionFormat>(formatComboBox->currentIndex());
        CompressionWorker::CompressionLevel level = 
            static_cast<CompressionWorker::CompressionLevel>(levelComboBox->currentIndex());
        
        compressionWorker->compressFiles(fileList, outputDirectory, format, level);
    });
    
    connect(compressionWorker, &CompressionWorker::compressionFinished,
            workerThread, &QThread::quit);
    connect(compressionWorker, &CompressionWorker::compressionFinished,
            compressionWorker, &CompressionWorker::deleteLater);
    connect(workerThread, &QThread::finished,
            workerThread, &QThread::deleteLater);
    
    // 启动线程
    enableControls(false);
    workerThread->start();
}

4. 文件压缩实现

核心压缩算法使用zlib库实现,支持ZIP和GZIP格式。

cpp 复制代码
// compressionworker.cpp - ZIP压缩实现
bool CompressionWorker::compressToZip(const QStringList &fileList, 
                                     const QString &outputPath,
                                     CompressionLevel level)
{
    QFile outputFile(outputPath);
    if (!outputFile.open(QIODevice::WriteOnly)) {
        return false;
    }
    
    QDataStream out(&outputFile);
    out.setByteOrder(QDataStream::LittleEndian);
    
    QList<QPair<QString, qint64>> fileEntries;
    qint64 centralDirectoryOffset = 0;
    
    // 写入每个文件的本地文件头和数据
    for (const QString &filePath : fileList) {
        QFileInfo fileInfo(filePath);
        QString relativePath = fileInfo.fileName();
        
        qint64 localHeaderOffset = outputFile.pos();
        
        if (!compressFileToZip(filePath, relativePath, out, level, fileEntries)) {
            return false;
        }
        
        // 检查是否取消操作
        {
            QMutexLocker locker(&cancelMutex);
            if (isCancelled) return false;
        }
    }
    
    centralDirectoryOffset = outputFile.pos();
    
    // 写入中央目录
    for (const auto &entry : fileEntries) {
        if (!writeCentralDirectoryEntry(entry.first, entry.second, out)) {
            return false;
        }
    }
    
    // 写入结束中央目录记录
    qint64 endCentralDirectoryOffset = outputFile.pos();
    quint16 totalEntries = fileEntries.size();
    
    // 写入结束中央目录记录
    out << quint32(0x06054b50);  // 签名
    out << quint16(0);           // 当前磁盘编号
    out << quint16(0);           // 中央目录开始磁盘编号
    out << quint16(totalEntries); // 当前磁盘上的条目数
    out << quint16(totalEntries); // 总条目数
    out << quint32(endCentralDirectoryOffset - centralDirectoryOffset); // 中央目录大小
    out << quint32(centralDirectoryOffset); // 中央目录偏移
    out << quint16(0);           // 注释长度
    
    return true;
}

5. 拖拽功能实现

支持文件拖拽到界面,提升用户体验。

cpp 复制代码
// mainwindow.cpp - 拖拽事件处理
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasUrls()) {
        event->acceptProposedAction();
    }
}

void MainWindow::dropEvent(QDropEvent *event)
{
    const QMimeData *mimeData = event->mimeData();
    
    if (mimeData->hasUrls()) {
        QStringList newFiles;
        
        for (const QUrl &url : mimeData->urls()) {
            QString localPath = url.toLocalFile();
            QFileInfo fileInfo(localPath);
            
            if (fileInfo.exists()) {
                if (fileInfo.isFile()) {
                    newFiles.append(localPath);
                } else if (fileInfo.isDir()) {
                    // 递归添加文件夹中的所有文件
                    QDirIterator it(localPath, QDir::Files | QDir::NoDotAndDotDot, 
                                   QDirIterator::Subdirectories);
                    while (it.hasNext()) {
                        newFiles.append(it.next());
                    }
                }
            }
        }
        
        // 添加到文件列表
        for (const QString &filePath : newFiles) {
            if (!fileList.contains(filePath)) {
                fileList.append(filePath);
            }
        }
        
        updateFileList();
        statusBar()->showMessage(QString("已添加 %1 个文件").arg(newFiles.size()), 3000);
    }
}

6. 进度显示和状态反馈

实时显示压缩进度和操作状态。

cpp 复制代码
// mainwindow.cpp - 进度更新
void MainWindow::onCompressionProgress(int percentage)
{
    progressBar->setValue(percentage);
    statusLabel->setText(QString("压缩进度: %1%").arg(percentage));
    statusBar()->showMessage(QString("正在压缩... %1%").arg(percentage));
}

void MainWindow::onCompressionFinished(bool success, const QString &message)
{
    progressBar->setValue(success ? 100 : 0);
    enableControls(true);
    
    if (success) {
        statusLabel->setText("压缩完成");
        statusBar()->showMessage("文件压缩成功", 3000);
        QMessageBox::information(this, "成功", "文件压缩完成!");
    } else {
        statusLabel->setText("压缩失败");
        statusBar()->showMessage("压缩失败", 3000);
        QMessageBox::critical(this, "错误", QString("压缩失败: %1").arg(message));
    }
}

项目特色

  1. 现代化界面设计:采用分组布局,界面清晰美观
  2. 多线程处理:后台压缩不阻塞界面操作
  3. 拖拽支持:提升用户操作体验
  4. 进度反馈:实时显示操作进度和状态
  5. 错误处理:完善的异常处理和用户提示
  6. 跨平台支持:基于Qt框架,支持多平台

编译运行

  1. 使用Qt Creator打开 18_FileCompressionTool.pro 文件
  2. 配置MinGW32编译器
  3. 构建并运行项目

总结

本项目展示了Qt桌面应用程序开发的完整流程,涵盖了界面设计、多线程处理、文件操作、信号槽机制等核心技术。通过这个项目,可以学习到:

  • Qt Widgets界面开发
  • 多线程编程和线程间通信
  • 文件压缩算法实现
  • 用户交互设计
  • 错误处理和用户体验优化

项目代码结构清晰,注释详细,适合作为Qt学习的教学案例。


源代码下载链接https://download.csdn.net/download/weixin_42059464/91725199

开发环境:Qt 5.9.9 + MinGW32 + Windows 10

相关推荐
L2ncE1 小时前
高并发场景数据与一致性的简单思考
java·后端·架构
武昌库里写JAVA1 小时前
使用 Java 开发 Android 应用:Kotlin 与 Java 的混合编程
java·vue.js·spring boot·sql·学习
小指纹1 小时前
河南萌新联赛2025第(六)场:郑州大学
java·开发语言·数据结构·c++·算法
叶~璃1 小时前
云计算:企业数字化转型的核心引擎
java
码luffyliu1 小时前
MySQL:MVCC机制及其在Java秋招中的高频考点
java·数据库·mysql·事务·并发·mvcc
程序员鱼皮1 小时前
这套 Java 监控系统太香了!我连夜给项目加上了
java·前端·ai·程序员·开发·软件开发
岁忧1 小时前
(nice!!!)(LeetCode 每日一题) 1277. 统计全为 1 的正方形子矩阵 (动态规划)
java·c++·算法·leetcode·矩阵·go·动态规划
律品1 小时前
pytest的前置与后置
开发语言·python·pytest
S妖O风F2 小时前
IDEA报JDK版本问题
java·ide·intellij-idea
Mr. Cao code2 小时前
使用Tomcat Clustering和Redis Session Manager实现Session共享
java·linux·运维·redis·缓存·tomcat