Search code examples
c++qtstatusbarprogress

Qt show constantly updating percentage in status bar


I have a program which load a file, does some calculations on the data, saves the data in memory and prints out to a text file.

I want to show the percentage of the processing progress in the status bar, I am using the following code:

    percent=file.pos()*10000/file.size();
    if((percent!=progress)&&(percent%5==1)){
        progress=percent/100;
        qDebug() << progress;
        progresslabel->setText(QString("Loading File: %1 \%").arg(progress));

Which is a part of the following function:

void MainWindow::CalcIntegral(){

    int percent,progress;
    progress=1;
    SingleLineData.resize(GRIDDIM*GRIDDIM);
    SingleLineData.fill(0);

    QString test;
    QString inputfile = QFileDialog::getOpenFileName(
                this,
                tr("Open Data File"),
                "/Users",
                "Data files (*.txt)"
                );

    if(inputfile == NULL)
        return;
        QFile file(inputfile);

  qDebug()<<"TEST";
        if(!file.open(QIODevice::ReadOnly)){
        }
    //    QTextStream in(&file);
    OpenFileData = new QTextStream(&file);

        double buffer;
        OpenFilePositions.resize(0);
        OpenFilePositions.push_back(-2);
        OpenFileData->readLine();
        progresslabel = new QLabel;
        ui->statusBar->addWidget(progresslabel);
        while(!OpenFileData->atEnd()){

            for(int i=0; i<512; i++){
                *OpenFileData >> buffer;
                SingleLineData[i]+=buffer;
            }

            percent=file.pos()*10000/file.size();
            if((percent!=progress)&&(percent%5==1)){
                progress=percent/100;
                qDebug() << progress;
                progresslabel->setText(QString("Loading File: %1 \%").arg(progress));


            }

    OpenFilePositions.push_back(OpenFilePositions.last()+6*(NUMBER_OF_AFE_CHIPS*AFECHANNELS)+1);

  }
        OpenFilePositions.removeFirst();
        OpenFilePositions.push_front(0);

  qDebug() << SingleLineData;
  qDebug() << OpenFilePositions.size();
  // ************* file output **************************************************

//  QString filename = QFileDialog::getSaveFileName(
//              this,
//              tr("Save File"),
//              "/Users",
//              "Text files (*.txt)"
//              );


  QString OutputFile = inputfile;
  OutputFile.replace(".txt","_integral.int");
  QFile fileout(OutputFile);
  fileout.open(QFile::WriteOnly);
  QTextStream out(&fileout);
  for(int i=0;i<512;i++){
      out<<SingleLineData[i]<<"\t";
  }

  fileout.close();
}

I can see the percentage constantly update in the console/application output thanks to qDebug() however the status bar only updates once the processing is complete and jumps right to 99%.

Any ideas how to make it update real time?

Cheers


Solution

  • You are updating progress status in a loop which blocks main GUI thread thus your label text does not get updated. That's because some event loop iterations should be done to update and process GUI related events. One possible solution is to use QApplication::processEvents in the while loop :

    ...
    progresslabel->setText(QString("Loading File: %1 \%").arg(progress));
    qApp->processEvents(QEventLoop::AllEvents);
    ...
    

    Another solution is to perform processing in a new thread and use a signal to report the progress status. Just prepare a signal in the worker thread which is emitted periodically and connect it to a slot which is in GUI thread and updates the label within the progress percentage.