Qprocess, qtimer and qprogressbar



  • In the code below my progressbar is set to visible and 0, but it's never updated until the routine finishes. Under Windows I get program not responding, although the routine goes on to finishes, give the proper qmessage, and re-hide the progressbar.
    @
    /////////////////////////////////////////////////////////////////////
    void MainWindow::TimerEvent()
    {
    int value = ui->progressBar->value();
    ui->progressBar->setValue(value+1);
    }

    ////////////////////////////////////////////////////////////////////////////
    void MainWindow::on_sideload_Button_clicked()
    {

    if (!isConnected)
       { QMessageBox::critical(
             this,
             tr("adbFire"),
             tr("Device not connected"));
          return;
    }
    

    command = "";

    QString fileName = QFileDialog::getOpenFileName(this,
          tr("Select app to install"), "/", tr("APK Files (*.apk)"));
    
    
    
    if (!fileName.isEmpty() )
    {
    
    QMessageBox::StandardButton reply;
      reply = QMessageBox::question(this, "Install", "Install "+fileName+"?",
                                    QMessageBox::Yes|QMessageBox::No);
      if (reply == QMessageBox::Yes)
      {
    
    
    
    
          QProcess *install_apk=new QProcess;
    
    
          install_apk->start(adbfile + " install -r " + fileName);
    
            ui->progressBar->setHidden(false);
            ui->progressBar->setValue(0);
            QTimer *timer = new QTimer(this);
            connect(timer, SIGNAL(timeout()), this, SLOT(TimerEvent()));
            timer->start(100);
    
          install_apk->waitForFinished(-1);
          command=install_apk->readAll();
          delete install_apk;
    
          if (command.contains("Success"))
           QMessageBox::information(
                          this,
                         "",
                          "Installed");
              else
               QMessageBox::critical(
                          this,
                          "",
                          "Install failed");
    
    
          }
    

    }

    ui->progressBar->setHidden(true);

      }
    

    @



  • According to the "doc":http://qt-project.org/doc/qt-5/qprocess.html#waitForFinished
    @
    install_apk->waitForFinished(-1);
    @
    "Blocks until the process has finished and the finished() signal has been emitted, or until msecs milliseconds have passed."
    You don't give Qt a chance to run an Event loop until the process is finished.



  • Thanks for your reply, I had no idea waitForFinished was such a bad citizen!

    Unfortunately, removing the waitForFinished(-1); breaks the code, the process quits before the external program finishes. Is there a way around my problem?



  • Simple solution for your case could be like that:
    @while(install_apk->state() != QProcess::NotRunning)
    qApp->processEvents();
    command=install_apk->readAll();
    delete install_apk;@

    But i recommend you use threads for such things.



  • Thanks so much!


Log in to reply
 

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