Program freeze when try to get MD5 of files
-
Did you check the examples from the documentation ?
-
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.
-
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
-
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
-
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; }"); } }
-
-
@saeid0034 said in Program freeze when try to get MD5 of files:
what i need to do?
fix your code to properly run the task in a separate thread.
-
@Christian-Ehrlicher my code
main.cpp
#include "user_def.h" #include "mainwindow2.h" #include... QString Md5_gen(QString const &s) { QString pakchunk_Md5; QCryptographicHash crypto(QCryptographicHash::Md5); QFile pakchunk("D:/Games/TDPA - Man of Medan" + 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; } int main(int argc, char *argv[]) { QApplication a(argc, argv); a.setStyle(new DarkStyle); FramelessWindow framelessWindow; framelessWindow.setWindowIcon(a.style()->standardIcon(QStyle::SP_DesktopIcon)); MainWindow *mainWindow = new MainWindow; framelessWindow.setContent(mainWindow); framelessWindow.show(); return a.exec(); }
user_def.h
#ifndef USER_DEF_H #define USER_DEF_H #include <QString> QString Md5_gen(QString const &s); #endif // USER_DEF_H
mainwindow2.h
#ifndef MAINWINDOW2_H #define MAINWINDOW2_H #include <QMainWindow> #include <QtConcurrentRun> #include <QFuture> #include <QFutureWatcher> #include <QThread> #include <QThreadPool> #include "user_def.h" namespace Ui { class MainWindow2; } class MainWindow2 : public QMainWindow { Q_OBJECT public: explicit MainWindow2(QWidget *parent = nullptr); ~MainWindow2(); public slots: void run_thread(); void displayFinishedBox(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_radioButton_2_clicked(); void on_radioButton_4_clicked(); void on_radioButton_3_clicked(); void on_radioButton_clicked(); private: Ui::MainWindow2 *ui; QFutureWatcher<QString> *watcher; QFuture<QString> *future; }; #endif // MAINWINDOW2_H
mainwindow2.cpp
#include... MainWindow2::MainWindow2(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow2) { ui->setupUi(this); connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow2::run_thread); // display a message box when the calculation has finished future = new QFuture<QString>; watcher = new QFutureWatcher<QString>; connect(watcher, SIGNAL(finished()), this, SLOT(displayFinishedBox())); } MainWindow2::~MainWindow2() { delete ui; } void MainWindow2::run_thread() { int file_ok = 0; //file pak33 QString loc33 = "/SM/test1.pak"; QFuture<QString> future33 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc33); watcher->setFuture(future33); QString pakchunk33 = future33.result(); 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; }"); } ui->progressBar->setValue(12); //file pak34 QString loc34 = "/SM/test2.pak"; QFuture<QString> future34 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc34); watcher->setFuture(future34); QString pakchunk34 = future34.result(); qDebug() << pakchunk34; 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; }"); } ui->progressBar->setValue(25); //file pak35 QString loc35 = "/SM/test3.pak"; QFuture<QString> future35 = QtConcurrent::run(QThreadPool::globalInstance(), Md5_gen, loc35); watcher->setFuture(future35); QString pakchunk35 = future35.result(); 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; }"); } ui->progressBar->setValue(38); /*Some other code*/
i dont know what is problem on this code
-
@saeid0034 said in Program freeze when try to get MD5 of files:
i dont know what is problem on this code
You don't read the post from others:
As @SGaist already said, calling result() when the future is not done yet will block your event loop.
-
@Christian-Ehrlicher i follow
@aha_1980 said in Program freeze when try to get MD5 of files:
see e.g. this example.
example, i read QtConcurrent doc and try to use it with watcher but after all i dont have any luck