QDialog with Progress Meter does not update
-
I have a series of database transactions that take a bit of time so I wanted to pop up a QDialog with a Progress Meter that shows the user some progress after each transaction. The problem is the Dialog launches but shows blank until I hit 100% then shows up. So I assume I have to trigger some sort of update but can't figure it out. Below is the code.
SyncProgress::SyncProgress(QWidget *parent) :
QDialog(parent),
ui(new Ui::SyncProgress)
{
ui->setupUi(this);
ui->btnOk->setEnabled(false);
connect(this, SIGNAL(completedSync()), this, SLOT(enableOk()));
connect(ui->btnOk, SIGNAL(clicked()), this, SLOT(close()));
}SyncProgress::~SyncProgress()
{
delete ui;
}void SyncProgress::enableOk()
{
ui->btnOk->setEnabled(true);
}void SyncProgress::setProgress(int inProgress)
{
ui->progressBar->setValue(inProgress);if(inProgress == 100) { emit completedSync(); }
}
//Then I call this it like this. The queries are repeated several times
QMessageBox msgBox(this);
msgBox.setText("About to Synchronize the Databases. Please wait for completion");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
int response = msgBox.exec();if(response != QMessageBox::Cancel) { SyncProgress *progressGUI = new SyncProgress(); connect(this, SIGNAL(sentSyncDataUpdate(int)), progressGUI, SLOT(setProgress(int))); progressGUI->show(); emit sentSyncDataUpdate(0); QSqlDatabase localDB; QSqlDatabase networkDB; QString subStr("C:"); QString replaceString("Z:"); QString networkDBPath = databasePath; networkDBPath.replace(networkDBPath.indexOf(subStr), subStr.size(), replaceString); QString networkDBLocation = networkDBPath; QFileInfo checkFile(networkDBPath); if (!checkFile.exists()) { qDebug() << "The Drive Not Available"; return; } //Open the location of the Network Database. if(!QSqlDatabase::contains("NETWORK")) { networkDB = QSqlDatabase::addDatabase("QSQLITE", "NETWORK"); networkDB.setDatabaseName(networkDBLocation); } else { networkDB = QSqlDatabase::database("QSQLITE", "NETWORK"); networkDB.setDatabaseName(networkDBLocation); } bool success = networkDB.open(); if(success == false) { const QSqlError error = networkDB.lastError(); qDebug() << "Network Data not Opened - Check Z Drive Connection- Error is " << error.text(); updateConsoleLog("Network Data not Opened - Check Z Drive Connection - Error is " + error.text()); return; } //Open the local database where we will delete all records. if(!QSqlDatabase::contains("LOCALDB")) { localDB = QSqlDatabase::addDatabase("QSQLITE", "LOCALDB"); } else { localDB = QSqlDatabase::database("QSQLITE", "LOCALDB"); } localDB.setDatabaseName(databasePath); //Attach the local database on the C: Drive QString sqlString = "ATTACH DATABASE '" + databasePath + "' AS toMerge"; QSqlQuery query(networkDB); query.prepare(sqlString); success = query.exec(); query.finish(); /////////////////////SYNC ACCEL DATA/////////////////////////////// //Copy the Accel Data query.prepare("INSERT INTO AccelData SELECT * FROM toMerge.AccelData"); success = query.exec(); query.finish(); emit sentSyncDataUpdate(5); if(success == true) { updateConsoleLog(QDateTime::currentDateTime().toString() + " / Sync AccelData Successful"); //Now the Sync is complete so we will clear the database if( localDB.open() ) { QString strDelete = "DELETE FROM AccelData"; QSqlQuery deleteQuery(localDB); deleteQuery.prepare(strDelete); if(deleteQuery.exec()) { updateConsoleLog(QDateTime::currentDateTime().toString() + " / Deleted Local AccelData"); } deleteQuery.isActive(); deleteQuery.finish(); localDB.close(); emit sentSyncDataUpdate(10); } //Now perform a search and removal of duplicate records. sqlString = "DELETE FROM AccelData WHERE rowid NOT IN (SELECT MAX(rowid) FROM AccelData GROUP BY TimeStamp)"; query.prepare(sqlString); success = query.exec(); query.finish(); emit sentSyncDataUpdate(15); } else { updateConsoleLog(QDateTime::currentDateTime().toString() + " / Sync AccelData Failed"); } //After the queries I call this emit sentSyncDataUpdate(100);
-
Hi,
The way you call your queries is such that the event loop doesn't get the chance to run in between to update your dialog. One way to do it is to call
qApp->processEvents()
between two steps.On a side note, you have a memory leak since you never delete progressGUI. One additional thing, you don't really need to use signals and slots here since you are updating the dialog in the same scope you are creating it, you can call setProgress directly.
-
For the signals and slots to work, the event loop must run, so a while loop or a long sequence of action requiring a lot of process will block it.