Qprocess show stdoutput only on ending of excecution.
-
I 'm using QProcess to launch a external application. (st-link_cli.exe)
if I excecute the application on cmd.exe, I can see the progress of the software but when I excecute on Qprocess I have a signal only on end off execution and I can't show the progress of the app.
There is another signal that can I use?process = new QProcess(this); QStringList argumentos; process->setWorkingDirectory(QDir::home().absolutePath()); QString file = "ST-LINK_CLI.exe"; qWarning(file.toStdString().c_str()); argumentos << "-P" << filehex << "-Q" << "-V" << "after_programming"; process->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput); connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(process, SIGNAL(readyRead()), this, SLOT(readOutput())); connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(stlinkFinish())); process->start(file,argumentos);
-
I 'm using QProcess to launch a external application. (st-link_cli.exe)
if I excecute the application on cmd.exe, I can see the progress of the software but when I excecute on Qprocess I have a signal only on end off execution and I can't show the progress of the app.
There is another signal that can I use?process = new QProcess(this); QStringList argumentos; process->setWorkingDirectory(QDir::home().absolutePath()); QString file = "ST-LINK_CLI.exe"; qWarning(file.toStdString().c_str()); argumentos << "-P" << filehex << "-Q" << "-V" << "after_programming"; process->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput); connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(process, SIGNAL(readyRead()), this, SLOT(readOutput())); connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(stlinkFinish())); process->start(file,argumentos);
-
@JNBarchan
Sorry, I missed that line accidentally.
after the previous lines, I make:process->start(file,argumentos);
-
@saran
It would be clearer if you edited your sample code to put this in wherever you call it. At least for me :) -
@saran
There seem to be two possibilities for your issue. I'm not sure which:-
I may well be misunderstanding your code (I have never done
QProcess
stuff), but are you sure you have your read/write stdin/stdout the right way round between your parent & child process? You want your main program to be reading its stdin from your subprocess which is writing to its stdout, from what you describe. My impression looking at your code is that you are connecting your program's stdout to the child process's "read channel", which is the opposite way round. Before you/I waste any time on this, am I right or wrong? -
If it's not that, the usual culprit is buffering of output in the child process, so that when it writes stuff your parent application does not yet get to actually read it till it gets flushed/process exits.
-
-
@saran
There seem to be two possibilities for your issue. I'm not sure which:-
I may well be misunderstanding your code (I have never done
QProcess
stuff), but are you sure you have your read/write stdin/stdout the right way round between your parent & child process? You want your main program to be reading its stdin from your subprocess which is writing to its stdout, from what you describe. My impression looking at your code is that you are connecting your program's stdout to the child process's "read channel", which is the opposite way round. Before you/I waste any time on this, am I right or wrong? -
If it's not that, the usual culprit is buffering of output in the child process, so that when it writes stuff your parent application does not yet get to actually read it till it gets flushed/process exits.
-
-
@JNBarchan
- The read channel is ok, when the process finish, I get the output.
- I probed QIODevice::Unbuffered option on process->start but still not working.
-
@saran
Thanks for clarifying.
Is your code your own, or is it taken from an example somewhere?
Are you saying you never receiveSIGNAL(readyReadStandardOutput())
norSIGNAL(readyRead())
, but onlySIGNAL(finished)
? -
@JNBarchan
Is my own code, based on examples.
I recieve both,SIGNAL(readyReadStandardOutput)
and themSIGNAL(finished)
.
The software output when you open it on a cmd.exe is something like this:
@saran
Your question states:when I excecute on Qprocess I have a signal only on end off execution
Now you say:
I recieve both, SIGNAL(readyReadStandardOutput) and them SIGNAL(finished).
Am I being dense, but I'm getting more confused?
Your code shows 3 signal handlers. Can you state nice & clearly which ones you do and do not get, and when?
-
I 'm using QProcess to launch a external application. (st-link_cli.exe)
if I excecute the application on cmd.exe, I can see the progress of the software but when I excecute on Qprocess I have a signal only on end off execution and I can't show the progress of the app.
There is another signal that can I use?process = new QProcess(this); QStringList argumentos; process->setWorkingDirectory(QDir::home().absolutePath()); QString file = "ST-LINK_CLI.exe"; qWarning(file.toStdString().c_str()); argumentos << "-P" << filehex << "-Q" << "-V" << "after_programming"; process->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput); connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(process, SIGNAL(readyRead()), this, SLOT(readOutput())); connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(stlinkFinish())); process->start(file,argumentos);
@saran said in Qprocess show stdoutput only on ending of excecution.:
process->start(file,argumentos);
Can you show what you're doing after this line?
Also why do you have this
process->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput);
?
What are you doing in readOutput()?
One more question: to which channel does this executable write (stdout or stderr)?
-
@saran said in Qprocess show stdoutput only on ending of excecution.:
process->start(file,argumentos);
Can you show what you're doing after this line?
Also why do you have this
process->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput);
?
What are you doing in readOutput()?
One more question: to which channel does this executable write (stdout or stderr)?
@jsulm said in Qprocess show stdoutput only on ending of excecution.:
One more question: to which channel does this executable write (stdout or stderr)?
Because he is using
setProcessChannelMode(QProcess::MergedChannels)
the executable will effectively only write tostdout
, notstderr
. http://doc.qt.io/qt-5/qprocess.html:[QProcess::MergedChannels] QProcess merges the output of the running process into the standard output channel (stdout). The standard error channel (stderr) will not receive any data. The standard output and standard error data of the running process are interleaved.
-
@saran said in Qprocess show stdoutput only on ending of excecution.:
process->start(file,argumentos);
Can you show what you're doing after this line?
Also why do you have this
process->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput);
?
What are you doing in readOutput()?
One more question: to which channel does this executable write (stdout or stderr)?
@jsulm
process->start is the last line.
I haveprocess->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput);
Just to make sure the process writes to stdout but anyway, without those lines the behavior is the same.
On readOutput I have:
void softsWindow::readOutput(){ qWarning(QString::number(process->bytesAvailable()).toStdString().c_str()); while(process->canReadLine()){ QByteArray linea = process->readLine(); ui->textBrowser->append(linea); } }
As you can see, the function directs the text of the stdout to a QTextBrowser
With theqWarning(QString::number(process->bytesAvailable()).toStdString().c_str());
line, I can see that the function receives all the data at once. the line print a "677" on application output, at same time the QTextBrowser print all the output. -
@jsulm
process->start is the last line.
I haveprocess->setReadChannel(QProcess::StandardOutput); process->setProcessChannelMode(QProcess::MergedChannels); process->setCurrentReadChannel(QProcess::StandardOutput);
Just to make sure the process writes to stdout but anyway, without those lines the behavior is the same.
On readOutput I have:
void softsWindow::readOutput(){ qWarning(QString::number(process->bytesAvailable()).toStdString().c_str()); while(process->canReadLine()){ QByteArray linea = process->readLine(); ui->textBrowser->append(linea); } }
As you can see, the function directs the text of the stdout to a QTextBrowser
With theqWarning(QString::number(process->bytesAvailable()).toStdString().c_str());
line, I can see that the function receives all the data at once. the line print a "677" on application output, at same time the QTextBrowser print all the output.@saran
Do two things:-
Replace
while(process->canReadLine())
and theprocess->readLine();
byQProcess::readAllStandardOutput()
. It avoids looping and relying on whenprocess->canReadLine()
returns true. (It also means we can try "unbufferred", whichcanReadLine()
says it cannot handle; you might want to retryQIODevice::Unbuffered
to see if that now makes any difference.) I would think about doing it like that anyway, unless you have reason to want to only grab whole lines at a time for output. -
Replace the command you're executing by one which produces voluminous output, e.g.
dir /s c:\
. What arrives when? Does the subprocess actually get stuck because the parent has failed to read its output as it goes along, which is what will happen if the signal only ever arrives at the end? We need to know whether behaviour is linked to
howst-link_cli.exe
produces its output versus anything else.
BTW, if when you last ran it returned just "677" as you say, that does not correspond at all to the output you show in your screenshot. Please try to keep things consistent since we are measuring when output arrives.
-
-
@saran
Do two things:-
Replace
while(process->canReadLine())
and theprocess->readLine();
byQProcess::readAllStandardOutput()
. It avoids looping and relying on whenprocess->canReadLine()
returns true. (It also means we can try "unbufferred", whichcanReadLine()
says it cannot handle; you might want to retryQIODevice::Unbuffered
to see if that now makes any difference.) I would think about doing it like that anyway, unless you have reason to want to only grab whole lines at a time for output. -
Replace the command you're executing by one which produces voluminous output, e.g.
dir /s c:\
. What arrives when? Does the subprocess actually get stuck because the parent has failed to read its output as it goes along, which is what will happen if the signal only ever arrives at the end? We need to know whether behaviour is linked to
howst-link_cli.exe
produces its output versus anything else.
BTW, if when you last ran it returned just "677" as you say, that does not correspond at all to the output you show in your screenshot. Please try to keep things consistent since we are measuring when output arrives.
@JNBarchan
When I said that I get "677", I was talking about theqWarning(QString::number(process->bytesAvailable()).toStdString().c_str());
line, this is consistent, when readOutput function is executed, all stdout bytes are availables for read, soprocess->bytesAvailable()
is 677, that is the characters count.
The screenshot shows the output when I run st-link_cli.exe on cmd.exe, as astated above. -
-
@JNBarchan
When I said that I get "677", I was talking about theqWarning(QString::number(process->bytesAvailable()).toStdString().c_str());
line, this is consistent, when readOutput function is executed, all stdout bytes are availables for read, soprocess->bytesAvailable()
is 677, that is the characters count.
The screenshot shows the output when I run st-link_cli.exe on cmd.exe, as astated above.@saran
OIC, that's because it has 677 bytes initially, then it manages to keep satisfying thecanReadLine
with more data which has arrived since, I guess. WE could have done with anotherqWarning(QString::number(process->bytesAvailable()).toStdString().c_str());
inside the loop.Never mind about that. Suggest you try my 2 recommendations and report back :)
-
@saran
OIC, that's because it has 677 bytes initially, then it manages to keep satisfying thecanReadLine
with more data which has arrived since, I guess. WE could have done with anotherqWarning(QString::number(process->bytesAvailable()).toStdString().c_str());
inside the loop.Never mind about that. Suggest you try my 2 recommendations and report back :)
@JNBarchan
-
The same with the replaces. The problem is in the SIGNAL, that is not generating the trigger on each new line.
-
I tried the following and the code works as I expected:
QString file = "ping"; QStringList argumentos << "192.168.0.1"; process->start(file,argumentos);
Result: 5
SIGNAL(readyReadStandardOutput())
, on each one, the readOutoput function printed correctly the output on the QTextBrowser.So the problem is the st-link_cli.exe output.
-
-
@JNBarchan
-
The same with the replaces. The problem is in the SIGNAL, that is not generating the trigger on each new line.
-
I tried the following and the code works as I expected:
QString file = "ping"; QStringList argumentos << "192.168.0.1"; process->start(file,argumentos);
Result: 5
SIGNAL(readyReadStandardOutput())
, on each one, the readOutoput function printed correctly the output on the QTextBrowser.So the problem is the st-link_cli.exe output.
-
-
@saran
Yes, like it's being buffered there so you don't get it, that's the usual problem I suspected at start. Try theQIODevice::Unbuffered
now assuming you've changed to useQProcess::readAllStandardOutput()
instead ofprocess->readLine();
? -
@JNBarchan
There is noSIGNAL(readyReadStandardOutput()
norSIGNAL(readyRead()
when I putQIODevice::Unbuffered
.