[SOLVED] QProcess, cannot read all the output sent by the process
-
Hello,
Sorry if this post is duplicated, I tried to post it yesterday but I couldn't.
I have a problem with the I/O from QProcess, I can't get all the output from the process.
I coded a simple test program (called PrintConsole.exe) which prints 1000 * 10 * 2 lines to stdout and stderr.@
#include <iostream>
using namespace std;
int main()
{
string s;
int j = 0;
while (j++ < 1000)
{
for (int i = 0; i < 10; i++)
{
s.clear();
s.insert(0, 80, to_string(i)[0]);
cout << "COUT " << to_string(j) << " -> " << s << endl;
cerr << "CERR " << to_string(j) << " -> " << s << endl;
}
}
return 0;
}@
The intial part of the output is :
@
COUT 1 -> 000000000000000000000000000000000000000000000000000000000000000000000
00000000000
CERR 1 -> 000000000000000000000000000000000000000000000000000000000000000000000
00000000000
...
CERR 1 -> 999999999999999999999999999999999999999999999999999999999999999999999
99999999999
@and so on till COUT 1000 and CERR 1000.
This program is run from a Qt application by using QProcess. The output of the process is sent to a QTextBrowser, which is updated by the function updateInfoTextBox
The following code setup the QProcess process
@
process = new QProcess(this);
connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(vbpFinished(int,QProcess::ExitStatus)));
connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(vbpError(QProcess::ProcessError)));
connect(process, &QProcess::readyReadStandardError, this, &BuildDialog::showVbpOutput );
connect(process, &QProcess::readyReadStandardOutput, this, &BuildDialog::showVbpOutput );@
where vbpFinished is
@
QString exitString =
QString("Process ")
+ document.getVbpCmdExe() + " finished with exit code "
+ QString::number(exitCode) + " and status "
+ (status == QProcess::NormalExit ? " normal " : " crashed");
qDebug() << exitString;html += "<b>" + exitString + " </b>"; updateInfoTextBox(html);
@
and showVbpOutput is
@
char buf[16384];
qint64 lineLength = 0;
lineLength = process->readLine(buf, sizeof(buf));
if (lineLength > 0)
{
html += QString(buf) + " <br />";
updateInfoTextBox(html);
}
@The problem is that the only text I got in the QTextBrowser is
@
COUT 1 -> 00000000000000000000000000000000000000000000000000000000000000000000000000000000
COUT 1 -> 11111111111111111111111111111111111111111111111111111111111111111111111111111111
COUT 1 -> 22222222222222222222222222222222222222222222222222222222222222222222222222222222
COUT 1 -> 33333333333333333333333333333333333333333333333333333333333333333333333333333333
COUT 1 -> 44444444444444444444444444444444444444444444444444444444444444444444444444444444
COUT 1 -> 55555555555555555555555555555555555555555555555555555555555555555555555555555555
COUT 1 -> 66666666666666666666666666666666666666666666666666666666666666666666666666666666
COUT 1 -> 77777777777777777777777777777777777777777777777777777777777777777777777777777777
COUT 1 -> 88888888888888888888888888888888888888888888888888888888888888888888888888888888
COUT 1 -> 99999999999999999999999999999999999999999999999999999999999999999999999999999999
COUT 2 -> 00000000000000000000000000000000000000000000000000000000000000000000000000000000
COUT 2 -> 11111111111111111111111111111111111111111111111111111111111111111111111111111111
COUT 2 -> 22222222222222222222222222222222222222222222222222222222222222222222222222222222
COUT 2 -> 33333333333333333333333333333333333333333333333333333333333333333333333333333333
COUT 2 -> 44444444444444444444444444444444444444444444444444444444444444444444444444444444
COUT 2 -> 55555555555555555555555555555555555555555555555555555555555555555555555555555555
COUT 2 -> 66666666666666666666666666666666666666666666666666666666666666666666666666666666
COUT 2 -> 77777777777777777777777777777777777777777777777777777777777777777777777777777777
COUT 2 -> 88888888888888888888888888888888888888888888888888888888888888888888888888888888
COUT 2 -> 99999999999999999999999999999999999999999999999999999999999999999999999999999999
COUT 3 -> 00000000000000000000000000000000000000000000000000000000000000000000000000000000
COUT 3 -> 11111111111111111111111111111111111111111111111111111111111111111111111111111111
COUT 3 -> 22222222222222222222222222222222222222222222222222222222222222222222222222222222
COUT 3 -> 33333333333333333333333333333333333333333333333333333333333333333333333333333333
Process PrintConsole.exe finished with exit code 0 and status normal
@Has anyone an idea why the output from the QProcess is truncated ?
Thank you,
Mario -
Hi,
AFAICS showVbpOutput only reads 16384 chars rather that all what is available. You should rather use readAll()
-
There is the possibility that there is text coming in while your program is still trying to display it, then something might get lost.
You can try something like the following which helped me:@
QByteArray bout=readAllStandardOutput();
if (m_bReadStdOut) {
//collect output
m_bout+=bout;
return;
}
if (m_bout.count() > 0) {
bout=m_bout+bout;
m_bout.clear();
}
if (bout.length() == 0)
return;
m_bReadStdOut=true;//display bout
m_bReadStdOut=false;
@using member variables m_bout and m_bReadStdOut
-
Thank you to both of you.
SGaist, you're right, by doing that way I read only 16k, if the output is bigger it would be skipped, even if in my output it is unusual to have a line longer than 200 or 300 chars.
I switched to readAllStandardOutput() and now works well, but the problem lied in a really stupid use I did of QTextBrowser.
Instead of appending the string by using the QTextEdit method append() I added the output of the process to a QString which were used with setText() of QTextBrowser. I think that when QString became really big QTextBrowser couldn't update the view with the content.Now I switched to append() and it works well.
Thank you again.Mario