QProgressDialog dont show Bar or Dialog is shown to late
-
Me again. I have a Problem i cant solve by my self. Its not clear for me whats wrong. i also tried to put the Code in a QThread, but nothing works.
The only Thing i want is a QProgressDialog. I have a Variable with Attachments and in these Attachments are Filepathes. I want to copy files and close the Form.
But the Problem is with my Code, that it only shows the Dialog Window, but not the Progressbar. For less then 1 second i can see 100% is poping and then the Form closes. Here is my Code.
void DiaryWindow::on_pbSave_clicked() { QProgressDialog progress("Saving...", "", 0, mAttachments.count(), this); progress.setWindowModality(Qt::WindowModal); progress.setCancelButton(0); progress.setValue(0); progress.show(); for (int i = 0; i <= mAttachments.count(); i++) { if (i < mAttachments.count()) { QString oldPath = mAttachments.at(i).absoluteFilePath(); QString newPath = mAppDataLocation + QString(QDir::separator()) + mAttachments.at(i).fileName(); while (QFile(newPath).exists()) { QString suffix = "." + QFileInfo(newPath).suffix(); newPath = QFileInfo(newPath).absolutePath() + QString(QDir::separator()) + mAttachments.at(i).baseName() + QString::number(i) + suffix; } QFile(oldPath).copy(oldPath, newPath); } else { //Database Actions } progress.setValue(i); } progress.setValue(mAttachments.count()); this->close(); }
Anyone has an Idea why my QProgressDialog isnt working correctly? I worked now for hourse on that and im really mad and tired.
-
@Fuel You're blocking the Qt event loop with your nested loops. That means: as long as on_pbSave_clicked() is executed the event loop is blocked and cannot handle the UI events. That's why you don't see your progress dialog working correctly. As a work around (not very clean solution) you can call http://doc.qt.io/qt-5/qcoreapplication.html#processEvents inside your for-loop.
QFile(oldPath).copy(oldPath, newPath); QApplication::processEvents();
In general you should avoid blocking operations in Qt. If you have such long lasting operations move them to a thread. But don't update UI in that thread! This is not supported. Instead emit a signal in this thread each time you want to update UI (progress dialog in your case) and in the slot you then update UI.
-
Really much thanks for your Help. I understand what you mean, but i dont know how to do that. Can you please give me some Pseudo Code? Or a Link? Just to understand.
I have know something like this
void DiaryWindow::on_pbSave_clicked() { mThread = new QThread(); mProgress = new QProgressDialog("Saving...", "", 0, mAttachments.count(), this); mProgress->setWindowModality(Qt::WindowModal); mProgress->setCancelButton(0); mProgress->setAttribute(Qt::WA_DeleteOnClose); mProgress->setValue(0); mProgress->show(); connect(mThread, SIGNAL(started()), this, SLOT(saving())); connect(mThread, SIGNAL(finished()), mThread, SLOT(deleteLater())); mThread->start(); if (mThread->isFinished()) this->close(); } void DiaryWindow::saving() { for (int i = 0; i <= mAttachments.count(); i++) { if (i < mAttachments.count()) { QString oldPath = mAttachments.at(i).absoluteFilePath(); QString newPath = mAppDataLocation + QString(QDir::separator()) + mAttachments.at(i).fileName(); while (QFile(newPath).exists()) { QString suffix = "." + QFileInfo(newPath).suffix(); newPath = QFileInfo(newPath).absolutePath() + QString(QDir::separator()) + mAttachments.at(i).baseName() + QString::number(i) + suffix; } QFile(oldPath).copy(oldPath, newPath); } else { //Database Actions } emit updateProgress(i); } } void DiaryWindow::updateProgress(int i) { mProgress->setValue(i); }
-
@Fuel I already gave you the code. Add this line
QApplication::processEvents();
inside your for-loop.
Or do you want to use a thread? In this case you should start here: http://doc.qt.io/qt-5/threads-technologies.html
Thisif (mThread->isFinished()) this->close();
should be removed. Close when thread finished.
In DiaryWindow::saving() you should emit a signal each time you copied a file. Connect a slot to this signal and in this slot update your progress dialog. -
I tried to do that now with QThread, but i dont success at all. Anyone has Example Code to show me how i do that? All Solutions i tried fails because of different Errors. I really dont have an Idea how to do that. Example Codes i found didnt help me. Please anyone has an good Example?
First i cant use GUI in a Thread. Then i got Errors that i cant send Events to a Object in a different Thread. And so on. I really had much of strange Errors.
-
@Fuel You should take a look at this: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
If you have any problems post your code, so others can help.