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);

  • Lifetime Qt Champion

    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.



  • Hi Thank you for the help. That did work and I see progress now. I did move the update so signals and slots thinking that may force and update but have since moved it back.


  • Lifetime Qt Champion

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.