如何读取QProcess输出

时间:2019-05-31 07:48:13

标签: qt signals stdout qprocess fflush

在Gui应用程序的主线程中,我正在启动另一个GUI应用程序的QProcess,它将随着时间的推移使用fputs()在stdout中记录一些消息。问题在于,经过一段时间后,以QProcess启动的GUI应用程序将冻结,因为其输出未被父级使用。我知道这是问题所在,因为如果我使用QIODevice :: NotOpen或QIODevice :: Unbuffered参数启动QProcess,它将不会卡住,但是将永远无法达到输出。 我试图将子进程的readyRead,readyReadStandardError,readyReadStandardOutput信号连接到父级的插槽中,但是由于某些原因,信号从不发出。每次写入后,我也会刷新标准输出。 我的问题是如何强制QProcess在不关闭数据的情况下实时发送一些数据?

信号的连接(T-是QProcess的包装器):

process->setWorkingDirectory(workingDir);
process->start(prog, argumentsList);
process->waitForStarted();
T* reciver = new V8QProcess(process);
QObject::connect(process, &QProcess::readyRead, reciver, &V8QProcess::OnMessageRecieved);
QObject::connect(process, &QProcess::readyReadStandardError, reciver, &V8QProcess::OnMessageRecieved);
QObject::connect(process, &QProcess::readyReadStandardOutput, reciver, &V8QProcess::OnMessageRecieved);

将登录到stdout的子流程的代码:

QByteArray bytes = LogMsg::getDisplayable(logMsg, 0).toUtf8();
fputs(bytes.constData(), stdout);
fflush(stdout);

OnMessageRecieved的代码:

 if (!p) { // p is the QProcess
    return;
}
QByteArray output;
output.append(p->readAllStandardError()).append(p->readAll());
QString message = QString::fromStdString(output.toStdString()); 

这种方法在运行Shell脚本或其他简单程序时有效。

1 个答案:

答案 0 :(得分:0)

我发现我的案子出了什么问题: 因为我是在QProcess中启动std::Thread,所以跳过了发生的事件(信号),因为std::Thread没有像QThread或{{ 1}}可以。 我使用的解决方案是:  1.使用QApplication代替QThread  2.不时致电std::thread

正确的解决方案是使用QCoreApplication::proccesEvents()来创建QThread::exec(),但是这种方法会阻止GUI应用程序,因此对我而言不是很好。