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