【发布时间】:2016-08-31 17:21:43
【问题描述】:
我必须在 QProcess 运行时获取它的输出。因此,我编写了以下代码:
CommandExecutor_C::CommandExecutor_C():
mProcessStatus(AI_UNKNOWN),
mOnTdiActiveCallback(),
mTdiProcess(new QProcess)
{
connect(mTdiProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(CheckOutput()));
connect(mTdiProcess, SIGNAL(readyReadStandardError()), this, SLOT(CheckOutput()));
}
void CommandExecutor_C::ExecuteCommand(QString &aCommand)
{
mTdiProcess->start(aCommand, QProcess::Unbuffered | QProcess::ReadWrite);
LOGINFO(FB_TDI,"Launch command: " + aCommand.toStdString());
}
void CommandExecutor_C::CheckOutput()
{
QString StdOut = QString(mTdiProcess->readAllStandardOutput());
QString StdErr = QString(mTdiProcess->readAllStandardError());
mProcessStatus = CheckTdiAutomationInterface(StdOut.toStdString(), StdErr.toStdString());
if(mProcessStatus != AI_UNKNOWN)
{
OnTdiActive(mProcessStatus);
}
}
如果 QProcess 完成,这可以正常工作,但在我的情况下,Process 会启动一个自动化界面,该界面应该永久在后台运行。因此,我使用了“readyReadStandardOutput”并将其连接到插槽 CheckOutput()。仅当进程完成时才会调用 CheckOutput()。否则我等不及了。
我在谷歌上搜索了很多关于这个问题的信息,但没有任何效果。我非常确定输出正在缓冲,并且如果进程完成则返回。因此,我在无缓冲模式下启动了进程。我也尝试过转发 mTdiProcess 的频道。这里是代码:
void CommandExecutor_C::ExecuteCommand(QString &aCommand)
{
mTdiProcess->setProcessChannelMode(QProcess::ForwardedChannels);
mTdiProcess->start(aCommand, QProcess::Unbuffered | QProcess::ReadWrite);
LOGINFO(FB_TDI,"Launch command: " + aCommand.toStdString());
}
但没有任何效果。我希望你能帮助我。
如果这很重要,我正在使用 Qt 5.4.2。
【问题讨论】:
-
也许你应该坚持使用信号
stateChanged(),因为在这种情况下似乎不会发出readyReadStandardOutput(),这对于文档来说似乎是正确的。如果你想要一个更频繁地报告的QProcess,那么创建你自己的进程类,它继承自QProcess。我认为这是正确的方式。 -
您正在运行的实际进程(由
QProcess对象管理)可能也在缓冲其标准输出。你确定这没有发生吗? -
"如果您想要一个报告频率更高的 QProcess,请创建您自己的继承自 QProcess 的流程类。" @maxik
-
这是一个想法,但如何?我不知道如何停用缓冲,因为 QProcess::Unbuffered 不起作用。而且我不认为 statechanged() 是正确的信号,因为它是为 QCheckBox 制作的。也许 bnaecker 是对的,标准输出被缓冲了。但是如何检查呢?