Unsolved Program freeze when try to get MD5 of files
-
Hi im using this code for generate MD5 of files in QT
QString Md5_gen(QString const &s) { QString pakchunk_Md5; QCryptographicHash crypto(QCryptographicHash::Md5); QFile pakchunk(QDir::currentPath() + s); if (pakchunk.open(QFile::ReadOnly)) { while(!pakchunk.atEnd()){ crypto.addData(pakchunk.read(8192)); } } else { qDebug() << "Can't open file."; pakchunk_Md5 = "nofile"; return pakchunk_Md5 } pakchunk_Md5 = crypto.result().toHex(); return pakchunk_Md5; }
its work well, but problem is when program start to generate MD5 of files, gui Freeze until all MD5 generated.
how can i fix this problem? -
Hi,
One way is to offload the work using QtConcurrent.
-
@saeid0034 said in Program freeze when try to get MD5 of files:
crypto.addData(pakchunk.read(8192));
Please note that you are also wasting RAM using this approach. Use the QIODevice overload to get the same result - without a loop and with less memory used.
-
Also, you probably should add
return pakchunk_Md5;
in yourelse
block. -
@sierdzio thanks yes you are right, i edited my code
and about using QIODevice, do you have any example for it? -
@SGaist thanks for reply, do you have any example close to my problem?
-
Did you check the examples from the documentation ?
-
@SGaist i need to use what function of QtConcurrent?
-
i use this code (i dont know if its right or not)
QString loc40 = "/file/test.pak"; QFuture<QString> future40 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc40); QString pakchunk40 = future40.result();
but program freeze again
-
As explained in the result documentation, it will block if the computation is not done. Use QFutureWatcher with signals and slots to properly make things asynchronous.
-
@SGaist The computation is done
Because the outputs are correct after the program exits From freeze, the only problem is program freeze, no matter how i try, and i sure problem coming from MD5 Generation -
i test Q In my code
QFutureWatcher<void>* watcher = new QFutureWatcher<void>(); connect(watcher, SIGNAL(finished()), this, SLOT(Md5_gen())); watcher->setFuture(future33);
It is wrong or ok?
i dont know how add my function to slot, i just put my md5 function name on it -
here is my full code for now
QString Md5_gen(QString const &s) { QString pakchunk_Md5; QCryptographicHash crypto(QCryptographicHash::Md5); QFile pakchunk(QDir::currentPath() + s); if (pakchunk.open(QIODevice::ReadOnly)) { while(!pakchunk.atEnd()){ crypto.addData(pakchunk.read(8192)); } } else { qDebug() << "Can't open file."; pakchunk_Md5 = "nofile"; return pakchunk_Md5; } pakchunk_Md5 = crypto.result().toHex(); return pakchunk_Md5; } MainWindow2::MainWindow2(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow2) { ui->setupUi(this); } MainWindow2::~MainWindow2() { delete ui; } void MainWindow2::on_pushButton_clicked() { int file_ok = 0; QFutureWatcher<void>* watcher = new QFutureWatcher<void>(); connect(watcher, SIGNAL(finished()), this, SLOT(Md5_gen())); //file pak33 QString loc33 = "/SM/test.pak"; QFuture<QString> future33 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc33); QString pakchunk33 = future33.result(); watcher->setFuture(future33); qDebug() << pakchunk33; if (pakchunk33 == "f7002d4419cd235a87746715ba6fb2ea") { qDebug() << "OK"; file_ok++; ui->label_8->setText("OK"); ui->label_8->setStyleSheet("QLabel { color : green; }"); } else if (pakchunk33 == "nofile") { qDebug() << "no file found"; ui->label_8->setText("not found"); ui->label_8->setStyleSheet("QLabel { color : red; }"); } else { qDebug() << "file is diffrent"; ui->label_8->setText("wrong"); ui->label_8->setStyleSheet("QLabel { color : red; }"); } //file pak34 QString loc34 = "/SM/test2.pak"; QFuture<QString> future34 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc34); QString pakchunk34 = future34.result(); qDebug() << pakchunk34; watcher->setFuture(future34); if (pakchunk34 == "64c77598586b6c3cb60beed0b0750620") { qDebug() << "OK"; file_ok++; ui->label->setText("OK"); ui->label->setStyleSheet("QLabel { color : green; }"); } else if (pakchunk34 == "nofile") { qDebug() << "no file found"; ui->label->setText("not found"); ui->label->setStyleSheet("QLabel { color : red; }"); } else { qDebug() << "file is diffrent"; ui->label->setText("wrong"); ui->label->setStyleSheet("QLabel { color : red; }"); } //file pak35 QString loc35 = "/SM/test3.pak"; QFuture<QString> future35 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc35); QString pakchunk35 = future35.result(); watcher->setFuture(future35); qDebug() << pakchunk35; if (pakchunk35 == "ee53f7a7656a32b5278c460baec46f16") { qDebug() << "OK"; file_ok++; ui->label_7->setText("OK"); ui->label_7->setStyleSheet("QLabel { color : green; }"); } else if (pakchunk35 == "nofile") { qDebug() << "no file found"; ui->label_7->setText("not found"); ui->label_7->setStyleSheet("QLabel { color : red; }"); } else { qDebug() << "file is diffrent"; ui->label_7->setText("wrong"); ui->label_7->setStyleSheet("QLabel { color : red; }"); } }
can anyone please help me find the problem
-
its fully fixed by adding
qApp->processEvents();
to MD5 while -
You do realise that your code is wrong in terms of offloading the work ? As I already wrote: result will be blocking if the computation is not finished.
The idea is to use the watcher so you let the computation run and in the slot connected to your QFutureWatcher you run your UI updates.
What you have here is mostly the same code as before, but more complicated, since you are blocking your event loop with your calls to
result
. -
Hi @saeid0034,
its fully fixed by adding qApp->processEvents(); to MD5 while
For sure not! Please don't use
processEvents()
if you don't know what you are doing!Regards
-
@SGaist i don't know how correctly use QFutureWatcher in my code...
As you can see in my full cod in above im add QFutureWatcher to my cod, is it wrong?
Can you please guide me to how do this? -
Hi @saeid0034,
As @SGaist already said, calling
result()
when the future is not done yet will block your event loop.You should call
result()
in the slot connected tofinished()
.Regards
-
@aha_1980 thanks for information
problem is i dont know much about working with slots and QFutureWatcher
can you please say to me i need to do what with this code?QString Md5_gen(QString const &s) { QString pakchunk_Md5; QCryptographicHash crypto(QCryptographicHash::Md5); QFile pakchunk(QDir::currentPath() + s); if (pakchunk.open(QIODevice::ReadOnly)) { while(!pakchunk.atEnd()){ crypto.addData(pakchunk.read(8192)); } } else { qDebug() << "Can't open file."; pakchunk_Md5 = "nofile"; return pakchunk_Md5; } pakchunk_Md5 = crypto.result().toHex(); return pakchunk_Md5; } MainWindow2::MainWindow2(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow2) { ui->setupUi(this); } MainWindow2::~MainWindow2() { delete ui; } void MainWindow2::on_pushButton_clicked() { int file_ok = 0; QFutureWatcher<void>* watcher = new QFutureWatcher<void>(); connect(watcher, SIGNAL(finished()), this, SLOT(Md5_gen())); //file pak33 QString loc33 = "/SM/test.pak"; QFuture<QString> future33 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc33); QString pakchunk33 = future33.result(); watcher->setFuture(future33); qDebug() << pakchunk33; if (pakchunk33 == "f7002d4419cd235a87746715ba6fb2ea") { qDebug() << "OK"; file_ok++; ui->label_8->setText("OK"); ui->label_8->setStyleSheet("QLabel { color : green; }"); } else if (pakchunk33 == "nofile") { qDebug() << "no file found"; ui->label_8->setText("not found"); ui->label_8->setStyleSheet("QLabel { color : red; }"); } else { qDebug() << "file is diffrent"; ui->label_8->setText("wrong"); ui->label_8->setStyleSheet("QLabel { color : red; }"); } //file pak34 QString loc34 = "/SM/test2.pak"; QFuture<QString> future34 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc34); QString pakchunk34 = future34.result(); qDebug() << pakchunk34; watcher->setFuture(future34); if (pakchunk34 == "64c77598586b6c3cb60beed0b0750620") { qDebug() << "OK"; file_ok++; ui->label->setText("OK"); ui->label->setStyleSheet("QLabel { color : green; }"); } else if (pakchunk34 == "nofile") { qDebug() << "no file found"; ui->label->setText("not found"); ui->label->setStyleSheet("QLabel { color : red; }"); } else { qDebug() << "file is diffrent"; ui->label->setText("wrong"); ui->label->setStyleSheet("QLabel { color : red; }"); } //file pak35 QString loc35 = "/SM/test3.pak"; QFuture<QString> future35 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc35); QString pakchunk35 = future35.result(); watcher->setFuture(future35); qDebug() << pakchunk35; if (pakchunk35 == "ee53f7a7656a32b5278c460baec46f16") { qDebug() << "OK"; file_ok++; ui->label_7->setText("OK"); ui->label_7->setStyleSheet("QLabel { color : green; }"); } else if (pakchunk35 == "nofile") { qDebug() << "no file found"; ui->label_7->setText("not found"); ui->label_7->setStyleSheet("QLabel { color : red; }"); } else { qDebug() << "file is diffrent"; ui->label_7->setText("wrong"); ui->label_7->setStyleSheet("QLabel { color : red; }"); } }
-