3

I want to get the stdout from a QProcess into a QTextEdit. It works if I do it like this:

QObject::connect(process, SIGNAL(readyReadStandardOutput()),
                 this, SLOT(readStdOutput()));

and

void myClass::readStdOutput()
{
  teOutput->insertPlainText(process->readAllStandardOutput());
}

While the subprogramm continuously prints to stdout (tested in a terminal) the QTextEdit is only updated every couple of seconds with chunks of output.

HWende
  • 1,705
  • 4
  • 18
  • 30
  • I'm using a Win7 64bit machine, compiled program is 32bit. I use the program also on XP with the same problem. – HWende Apr 20 '12 at 08:25

2 Answers2

2

From the QIODevice manual:

Certain subclasses of QIODevice, such as QTcpSocket and QProcess, are asynchronous. This means that I/O functions such as write() or read() always return immediately, while communication with the device itself may happen when control goes back to the event loop. QIODevice provides functions that allow you to force these operations to be performed immediately, while blocking the calling thread and without entering the event loop.

Another thing to try would be to disable any buffer, the manual doesn't mention it for QProcess, but you could try it:

Some subclasses, such as QFile and QTcpSocket, are implemented using a memory buffer for intermediate storing of data. This reduces the number of required device accessing calls, which are often very slow.

...

QIODevice allows you to bypass any buffering by passing the Unbuffered flag to open().

Community
  • 1
  • 1
Silas Parker
  • 8,017
  • 1
  • 28
  • 43
  • 2
    I tried passing `QIODevice::Unbuffered` to `QProcess::start()` without success (you can pass it - but output is still coming in chunks). Thanks for the tip anyway. – HWende Apr 19 '12 at 08:08
  • See this possibly related question: http://stackoverflow.com/questions/3385427/disable-buffering-on-redirected-stdout-pipe-win32-api-c – Silas Parker Apr 19 '12 at 08:24
0

Calling waitForReadyRead() seems to trigger an update.

So, to update e.g. 10 times per second, after

QObject::connect(process, SIGNAL(readyReadStandardOutput()),
             this, SLOT(readStdOutput()));

add a

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(executeWaitForReadyRead()));
timer->start(100);

and

void YourClass::executeWaitForReadyRead()
{
    process->waitForReadyRead();
}
user2707001
  • 1,543
  • 12
  • 13