用Qt编写的计算文件MD5值的Demo

Dialog.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>329</width>
    <height>161</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MD5Hasher</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
     <item>
      <widget class="QLabel" name="filenameLabel">
       <property name="text">
        <string>文件:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="chooseFileButton">
       <property name="text">
        <string>选择文件...</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <widget class="QLineEdit" name="md5LineEdit">
     <property name="readOnly">
      <bool>true</bool>
     </property>
    </widget>
   </item>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_2">
     <item>
      <widget class="QProgressBar" name="md5ProgressBar">
       <property name="value">
        <number>0</number>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="hashButton">
       <property name="text">
        <string>Hash</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

MD5Thread.cpp

#include "MD5Thread.h"
#include <QCryptographicHash>

MD5Thread::MD5Thread(const QString &filename) : file(filename)
{
    qDebug("MD5Thread(const QString &) called");
}

MD5Thread::~MD5Thread()
{
    qDebug("~MD5Thread() called");
}

void MD5Thread::run()
{
    if (file.open(QFile::ReadOnly))
    {
        QCryptographicHash md5(QCryptographicHash::Md5);
        QByteArray buffer;
        qint64 addedDataSize = 0;
        while (!(buffer = file.read(10 * 1024 * 1024)).isEmpty())
        {
            md5.addData(buffer);
            emit dataAdded(static_cast<uint>((addedDataSize += buffer.size()) * 100.0 / file.size()));
        }
        emit md5Hashed(md5.result().toHex());
    }
}

main.cpp

#include "Dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

Dialog.cpp

#include "Dialog.h"
#include "ui_Dialog.h"
#include "MD5Thread.h"
#include <QFileDialog>
#include <QCloseEvent>
#include <QMessageBox>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    qDebug("Dialog(QWidget *) called");
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
    qDebug("~Dialog() called");
}

void Dialog::closeEvent(QCloseEvent *event)
{
    if (md5Thread)
    {
        if (!md5Thread->isFinished())
        {
            QMessageBox::critical(this, "Tip", "正在计算文件的MD5值!");
            event->ignore();
        }
    }
}

void Dialog::on_chooseFileButton_clicked()
{
    fileToHashMD5 = QFileDialog::getOpenFileName(this, "选择文件");
    if (!fileToHashMD5.isNull())
        ui->filenameLabel->setText(fileToHashMD5);
}

void Dialog::on_hashButton_clicked()
{
    if (!fileToHashMD5.isNull())
    {
        ui->hashButton->setEnabled(false);
        md5Thread = new MD5Thread(fileToHashMD5);
        connect(md5Thread, &MD5Thread::dataAdded, this, &Dialog::onMD5ThreadDataAdded);
        connect(md5Thread, &MD5Thread::md5Hashed, this, &Dialog::onMD5ThreadMD5Hashed);
        connect(md5Thread, &MD5Thread::finished, this, &Dialog::onMD5ThreadFinished);
        md5Thread->start();
    }
}

void Dialog::onMD5ThreadDataAdded(uint hashProgress)
{
    ui->md5ProgressBar->setValue(hashProgress);
}

void Dialog::onMD5ThreadMD5Hashed(const QByteArray &md5Data)
{
    ui->md5LineEdit->setText(md5Data);
    ui->hashButton->setEnabled(true);
}

void Dialog::onMD5ThreadFinished()
{
    md5Thread->deleteLater();
    md5Thread = Q_NULLPTR;
}

MD5Thread.h

#ifndef MD5THREAD_H
#define MD5THREAD_H

#include <QThread>
#include <QFile>
class MD5Thread : public QThread
{
    Q_OBJECT
signals:
    void dataAdded(uint hashProgress);
    void md5Hashed(const QByteArray &md5Data);
public:
    MD5Thread(const QString &filename);
    ~MD5Thread();
protected:
    void run();
private:
    QFile file;
};

#endif // MD5THREAD_H

Dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

namespace Ui {
class Dialog;
}

class MD5Thread;

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

protected:
    void closeEvent(QCloseEvent *event);

private:
    Ui::Dialog *ui;
    MD5Thread *md5Thread = Q_NULLPTR;
    QString fileToHashMD5;

private slots:
    void on_chooseFileButton_clicked();
    void on_hashButton_clicked();
    void onMD5ThreadDataAdded(uint hashProgress);
    void onMD5ThreadMD5Hashed(const QByteArray &md5Data);
    void onMD5ThreadFinished();

};

#endif // DIALOG_H
原文地址:https://www.cnblogs.com/buyishi/p/9017540.html