首页 > 代码库 > Inter-process communication in Qt using QProcess

Inter-process communication in Qt using QProcess

Recently, I needed to call a CUI program from within Qt GUI window and simulate the effect of an embedded command line window like the Autolisp console in AutoCAD. At the beginning, I wanted to implement this function using UNIX pipe. However, I found out there is a QProcess class, which brings more convenience. The procedures are obvious and shown as follows:

# Create QProcess objectcb = new Qprocess();# Start a child process with the inter-process communication mode set to ReadWrite and Unbufferedcb->start("./abbcbctrl", QStringList()<<"-g", QIODevice::ReadWrite | QIODevice::Unbuffered);# Connect signals with related slots: readyReadStandardOutput is emitted when the standard output buffer is ready for reading while readyReadStandardError is related to the standard errorconnect(cb, SIGNAL(readyReadStandardOutput()), this, SLOT(DumpStdOut()));connect(cb, SIGNAL(readyReadStandardError()), this, SLOT(DumpStdErr()));

The slot functions are as follows:

void MainWindow::DumpStdOut() {    QByteArray strdata = cb->readAllStandardOutput();    ui->txtCUI->setTextColor(Qt::green);    ui->txtCUI->append(strdata);}void MainWindow::DumpStdErr() {    QByteArray strdata = cb->readAllStandardError();    ui->txtCUI->setTextColor(Qt::red);    ui->txtCUI->append(strdata);}

When running the above program, it was strange to discover that the message sent from the child process couldn‘t be displayed immediately in the Qt GUI. Only when an enough quantity of characters arrived, they could be displayed. At first, I thought the problem might be asynchronous communication mode was used and neither the standard output nor the standard error buffer size could be changed. Therefore, I tried to used synchronous mode to read the output from child process periodically. However, this method caused the GUI interface did not response anymore. On the next day, an idea came to my mind that the problem might come from the child process, in which I did not call the fflush function after using printf. Here, the function fflush means enforce all the data exiting in the buffer to be dumped. If we directly run a CUI program in the terminal, the display of the characters is OK. This is because in the terminal, the string buffering is based upon the line ending character "\n". Whenever it meets "\n", it will automatically flush the buffer. However, when a child process sends information through pipe to the QProcess object in Qt, the buffering mechanism is different, i.e. only when the predefined buffer is full, the characters will then be actually output. The problem has finally been solved after adding the fflush function.