How do I make my QProgressDialog show the process of my task in the progress bar?
-
Hello guys, I have the following question, how do I so that in QProgressDialog, the progress bar is shown as my task progresses, I have tried and I have not succeeded yet.
Only the full bar is shown, as if it had already finished, but the task still continues to execute.
Here I leave my code, I hope you can help me, thanks in advance.
This is where I do my task, it is a static method, which does the decryption process, this at the same time calls a function called encryptPassword()
void MainWindow::encryptAllData(QStringList data, int rowCount){ QStringList dataEncrypt{}; for (int row = 0; row < rowCount; ++row) { auto rowData = data.value(row); dataEncrypt << encryptPassword(rowData); } for(int i = 0; i<dataEncrypt.count(); ++i){ qInfo() << dataEncrypt.value(i) << '\n'; } }Here is the code for the button that shows the QProgressDialog
QObject::connect(ui->pushButton, &QPushButton::clicked, this, [&](){ QStringList data; auto numRows {ui->tableWidget->rowCount()}; for (int row = 0; row < numRows; ++row) { data << ui->tableWidget->item(row, 1)->data(Qt::DisplayRole).toString(); } QProgressDialog progressDialog; progressDialog.setLabelText("Encriptando datos..."); QFutureWatcher<void> watcher{}; QObject::connect(&progressDialog, &QProgressDialog::canceled, &watcher, &QFutureWatcher<void>::cancel); QObject::connect(&watcher, &QFutureWatcher<void>::finished, &progressDialog, &QProgressDialog::reset); QObject::connect(&watcher, &QFutureWatcher<void>::progressRangeChanged, &progressDialog, &QProgressDialog::setRange); QObject::connect(&watcher, &QFutureWatcher<void>::progressValueChanged, &progressDialog, &QProgressDialog::setValue); QFuture<void> future = QtConcurrent::run(encryptAllData, data, numRows); watcher.setFuture(future); progressDialog.exec(); watcher.waitForFinished(); if(watcher.isCanceled()){ QMessageBox::warning(this, qApp->applicationName(), "El proceso fue cancelado!"); }else{ QMessageBox::information(this, qApp->applicationName(), "El proceso ha finalizado!"); } });The encryptPassword method code
QString MainWindow::encryptPassword(const QString& password) { QProcess process; QStringList arguments; arguments << "enc" << "-aes-256-cbc" << "-a" << "-pbkdf2" << "-pass" << "pass:password" << "-in" << "-" << "-out" << "-"; process.setProgram("openssl"); process.setArguments(arguments); process.start(); if (!process.waitForStarted()) { qDebug() << "Failed to start OpenSSL process."; return QString(); } process.write(password.toUtf8()); process.closeWriteChannel(); if (!process.waitForFinished()) { qDebug() << "Failed to encrypt password with OpenSSL."; return QString(); } QString encryptedPassword = process.readAllStandardOutput(); // encryptedPassword.remove('\n'); return encryptedPassword; } -
Hello guys, I have the following question, how do I so that in QProgressDialog, the progress bar is shown as my task progresses, I have tried and I have not succeeded yet.
Only the full bar is shown, as if it had already finished, but the task still continues to execute.
Here I leave my code, I hope you can help me, thanks in advance.
This is where I do my task, it is a static method, which does the decryption process, this at the same time calls a function called encryptPassword()
void MainWindow::encryptAllData(QStringList data, int rowCount){ QStringList dataEncrypt{}; for (int row = 0; row < rowCount; ++row) { auto rowData = data.value(row); dataEncrypt << encryptPassword(rowData); } for(int i = 0; i<dataEncrypt.count(); ++i){ qInfo() << dataEncrypt.value(i) << '\n'; } }Here is the code for the button that shows the QProgressDialog
QObject::connect(ui->pushButton, &QPushButton::clicked, this, [&](){ QStringList data; auto numRows {ui->tableWidget->rowCount()}; for (int row = 0; row < numRows; ++row) { data << ui->tableWidget->item(row, 1)->data(Qt::DisplayRole).toString(); } QProgressDialog progressDialog; progressDialog.setLabelText("Encriptando datos..."); QFutureWatcher<void> watcher{}; QObject::connect(&progressDialog, &QProgressDialog::canceled, &watcher, &QFutureWatcher<void>::cancel); QObject::connect(&watcher, &QFutureWatcher<void>::finished, &progressDialog, &QProgressDialog::reset); QObject::connect(&watcher, &QFutureWatcher<void>::progressRangeChanged, &progressDialog, &QProgressDialog::setRange); QObject::connect(&watcher, &QFutureWatcher<void>::progressValueChanged, &progressDialog, &QProgressDialog::setValue); QFuture<void> future = QtConcurrent::run(encryptAllData, data, numRows); watcher.setFuture(future); progressDialog.exec(); watcher.waitForFinished(); if(watcher.isCanceled()){ QMessageBox::warning(this, qApp->applicationName(), "El proceso fue cancelado!"); }else{ QMessageBox::information(this, qApp->applicationName(), "El proceso ha finalizado!"); } });The encryptPassword method code
QString MainWindow::encryptPassword(const QString& password) { QProcess process; QStringList arguments; arguments << "enc" << "-aes-256-cbc" << "-a" << "-pbkdf2" << "-pass" << "pass:password" << "-in" << "-" << "-out" << "-"; process.setProgram("openssl"); process.setArguments(arguments); process.start(); if (!process.waitForStarted()) { qDebug() << "Failed to start OpenSSL process."; return QString(); } process.write(password.toUtf8()); process.closeWriteChannel(); if (!process.waitForFinished()) { qDebug() << "Failed to encrypt password with OpenSSL."; return QString(); } QString encryptedPassword = process.readAllStandardOutput(); // encryptedPassword.remove('\n'); return encryptedPassword; }@lincoln
Regardless of whether your code is right or not, I don't get what you expecting? Running an external program to encrypt a password is (a) presumably going to take milliseconds and (b) won't report any kind of progress anyway. What is the use of a progress bar? -
@lincoln
Regardless of whether your code is right or not, I don't get what you expecting? Running an external program to encrypt a password is (a) presumably going to take milliseconds and (b) won't report any kind of progress anyway. What is the use of a progress bar?Well, it was a mistake, I am not calling an external process, but I have an encryption function which is this.
The call to openssl was just an alternative that I put in, and that I copied by mistake.
QString MainWindow::encryptText(const QString& text, const QString& key){ QByteArray encryptedData; QByteArray textData = text.toUtf8(); QByteArray keyData = key.toUtf8(); QCryptographicHash hash(QCryptographicHash::Sha512); hash.addData(keyData); QByteArray hashedKey = hash.result(); // Encriptar el texto utilizando AES for (int i = 0; i < textData.size(); ++i) { char encryptedChar = textData.at(i) ^ hashedKey.at(i % hashedKey.size()); encryptedData.append(encryptedChar); } return QString::fromUtf8(encryptedData.toBase64()); } -
Well, it was a mistake, I am not calling an external process, but I have an encryption function which is this.
The call to openssl was just an alternative that I put in, and that I copied by mistake.
QString MainWindow::encryptText(const QString& text, const QString& key){ QByteArray encryptedData; QByteArray textData = text.toUtf8(); QByteArray keyData = key.toUtf8(); QCryptographicHash hash(QCryptographicHash::Sha512); hash.addData(keyData); QByteArray hashedKey = hash.result(); // Encriptar el texto utilizando AES for (int i = 0; i < textData.size(); ++i) { char encryptedChar = textData.at(i) ^ hashedKey.at(i % hashedKey.size()); encryptedData.append(encryptedChar); } return QString::fromUtf8(encryptedData.toBase64()); }@lincoln
Seems to me my comment still stand. You want to show a progress bar while running code to encrypt a password which takes a fraction of a second? And even if it took longer it's not emitting a signal as it progresses that I can see. Where and when isprogressValueChanged()being emitted? You need something which takes a while and emits signals as it goes.I think you might want to look at https://stackoverflow.com/questions/23438044/how-to-communicate-a-progresstext-from-a-qtconcurrentrun-function-or-similar. The last post there shows how someone would need to use it. I would follow a comment to the solutuon:
I think using signals to report progress is the most convenient way when using QtConcurrent::run().