5

I have to get the output of a QProcess while it is running. Therefore I have written the following Code:

CommandExecutor_C::CommandExecutor_C():
  mProcessStatus(AI_UNKNOWN),
  mOnTdiActiveCallback(),
  mTdiProcess(new QProcess)
{
    connect(mTdiProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(CheckOutput()));
    connect(mTdiProcess, SIGNAL(readyReadStandardError()), this, SLOT(CheckOutput()));
}

void CommandExecutor_C::ExecuteCommand(QString &aCommand)
{
  mTdiProcess->start(aCommand, QProcess::Unbuffered | QProcess::ReadWrite);
  LOGINFO(FB_TDI,"Launch command: " + aCommand.toStdString());
}


void CommandExecutor_C::CheckOutput()
{
    QString StdOut = QString(mTdiProcess->readAllStandardOutput());
    QString StdErr = QString(mTdiProcess->readAllStandardError());

    mProcessStatus = CheckTdiAutomationInterface(StdOut.toStdString(), StdErr.toStdString());

    if(mProcessStatus != AI_UNKNOWN)
    {
      OnTdiActive(mProcessStatus);
    }
}

This works fine if QProcess gets finished but in my case the Process starts an automation interface which should run in background permanently. Therefore I have used "readyReadStandardOutput" and connect it to the slot CheckOutput(). CheckOutput() is getting called just if the process has been finished. Otherwise I am waiting endless.

I have googled a lot about the problem but nothing worked. I am very sure that the output is getting buffered and does just return if the Process has finished. Therefore I have started the Process in Unbuffered-Mode. I have also tried to forward the channels of mTdiProcess. Here the Code:

void CommandExecutor_C::ExecuteCommand(QString &aCommand)
{
  mTdiProcess->setProcessChannelMode(QProcess::ForwardedChannels);
  mTdiProcess->start(aCommand, QProcess::Unbuffered | QProcess::ReadWrite);
  LOGINFO(FB_TDI,"Launch command: " + aCommand.toStdString());
}

But nothing worked. I hope you can help me.

I am using Qt 5.4.2 if that's important.

Lehtim
  • 125
  • 1
  • 12
  • Maybe you should stick to the signal `stateChanged()` because `readyReadStandardOutput()` seems not to be emitted in this situation which seems to be correct regarding to the documentation. If you want a `QProcess` which reports more often then create your own process class which inherits from `QProcess`. This would be a correct way I think. – maxik Aug 23 '16 at 13:06
  • It's possible that the actual process you're running (managed by the `QProcess` object) is also buffering its standard output. Are you sure that's not happening? – bnaecker Aug 23 '16 at 16:12
  • "If you want a QProcess which reports more often then create your own process class which inherits from QProcess." @maxik – Lehtim Aug 24 '16 at 04:22
  • That would be an idea but how? I don't know how to deactivate the buffering because QProcess::Unbuffered does not work. And I don't think that statechanged() would be the right signal because its made for a QCheckBox. Maybe bnaecker is right and the standard output is buffered. But how to check this? – Lehtim Aug 24 '16 at 04:27

1 Answers1

4

I usually check the output in regular intervals like this:

bool returnBool = false;
while (returnBool == false)
{
    /*! Wait one second if the process finishes. Then read all output to
     * stdout and stderr and redo. */
    returnBool = process.waitForFinished(1000);
    QString outputStdOut = process.readAllStandardOutput();
    QString outputStdErr = process.readAllStandardError();
}
Sebastian
  • 181
  • 1
  • 4
  • I have tried something quit similar but it did not work in my case. And isn't that synchronously? I would suggest that the GUI will freeze while nothing was received. And its much better to use signals and slots instead like I have done because I am using a QProgressDialog (the bar does move from left to right while waiting). – Lehtim Aug 24 '16 at 11:18
  • You are right, that is synchronously. When you run this code from the GUI thread, it will freeze. If the signals work, then using them is of course better ... – Sebastian Aug 30 '16 at 10:14
  • this still not working in executables. but in other work. like pinging for example – greendino Oct 19 '20 at 09:52