Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Edge case problems
Qt 6.12 LTS is out! See what's new in the release blog

Edge case problems

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 2.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jocala
    wrote on last edited by
    #1

    I have a project out in user's hands and for the most part it's working well (OS X & Windows) but I'm getting the occasional edge case where the program goes non-responsive (progress bar fills to end and program sits there). If you look at the code below you'll see that I'm using QProcess and a progress bar. Most of the routines in my program are similar, using QProcess to send various commands to an external program (adb, android debug bridge). I can't duplicate these problems and I've tested using Windows XP, Windows 7 and OS X Mav. I thought perhaps resources, so I ran my code under XP with 1Gb of RAM: ran fine w/o issues. Unfortunately, it's all remote, no way I can directly observe.

    Any ideas?

    @
    ui->progressBar->setHidden(false);
    ui->progressBar->setValue(0);

          QTimer *timer = new QTimer(this);
          connect(timer, SIGNAL(timeout()), this, SLOT(TimerEvent()));
          timer->start(tsvalue);
    
    
          QProcess install_apk;
          install_apk.setProcessChannelMode(QProcess::MergedChannels);
          QString cstring = adb + " install -r " + '"'+ fileName+'"';
          install_apk.start(cstring);
    
           while(install_apk.state() != QProcess::NotRunning)
               qApp->processEvents();
    
           command=install_apk.readAll();
           
           ui->progressBar->setHidden(true);
    
           if (command.contains("Success"))
              QMessageBox::information(
                          this,
                         "",
                          "Installed");
              else
              QMessageBox::critical(
                          this,
                          "",
                          "Install failed");
    

    @

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      It's hard to say but a wild guess would be that you're not calling install_apk.waitForStarted(). If the process doesn't "start to start" before you get to the while loop it will be in the NotRunning state, so you'll skip to the readAll() which I don't know what does on the process that didn't start yet.

      In any case I would recommend to rewrite this part into a proper OO manner, where you have a worker object that starts the process and reads output in the slot responding to the finished() signal of the process. You wouldn't have to call processEvents() in a loop, which is always a good indicator of refactoring opportunity.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jocala
        wrote on last edited by
        #3

        Thanks. I'll give this some thought.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jocala
          wrote on last edited by
          #4

          If I understand correctly, I'm setting up a slot, "RunProcess". I pass it a value (cstring) then when the signal waitForFinished emits it returns the contents of readAll()?

          @
          QString MainWindow::RunProcess(QString cstring)
          {
          QProcess run_command;
          run_command.setProcessChannelMode(QProcess::MergedChannels);
          run_command.start(cstring);
          run_command.waitForFinished(-1);
          command=run_command.readAll();
          return command;
          }

          void MainWindow::on_sideload_Button_clicked()
          {

          QString cstring = adb + " install -r " + '"'+ fileName+'"';

          connect(QString command, SIGNAL(waitForFinished()), this, SLOT(RunProcess(cstring)));

          }
          @

          The slot RunProcess compiles, but the connect statement fails. Am I on the right track?

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            No, there is no signal waitForFinished. waitForFinished is a blocking method. There is a finished() signal.

            @
            class Foo : public QObject {
            Q_OBJECT
            public:
            Foo() {
            connect(&p, &QProcess::finished, this, &Foo::stuffEnded);
            }
            void doStuff() {
            ...
            p.start();
            }
            void stuffEnded(int exitCode, QProcess::ExitStatus exitStatus) {
            if(exitCode == 0)
            {
            p.readAllStandardOutput();
            ...
            }
            }
            private:
            QProcess p;
            };
            @

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt
            • Unsolved