在Gui应用程序的主线程中,我正在启动另一个GUI应用程序的QProcess,该应用程序将使用fput()在标准输出中记录一段时间内的一些消息。问题是,在一段时间后,使用QProcess启动的图形用户界面应用程序将冻结,因为它的输出不会被父应用程序使用。我知道这是个问题,因为如果我用QIODevice::NotOpen或QIODevice::Unbuffered参数启动QProcess,它不会卡住,但输出永远不会到达。我曾尝试将子进程的readyRead、readyReadStandardError、readyReadStandardOutput信号连接到父进程中的插槽,但由于某些原因,这些信号从未发出。我还会在每次写入后刷新stdout。我的问题是,如何强制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脚本或其他简单程序时有效。
发布于 2019-06-24 23:24:23
我发现了问题所在:因为我是在std::Thread中启动QProcess的,所以会跳过发生的事件(信号),因为std::Thread没有像QThread或QApplication那样的事件队列。我使用的解决方案是: 1.使用QThread代替std::thread 2.不定期调用QCoreApplication::proccesEvents()。
正确的解决方案是使用QThread::exec()来创建一个event loop,但是这种方法会阻塞图形用户界面应用程序,所以在我的例子中是不好的。
https://stackoverflow.com/questions/56390885
复制相似问题