【问题标题】:How to check if QProcess is executing correctly?如何检查 QProcess 是否正确执行?
【发布时间】:2025-03-28 13:35:02
【问题描述】:
QProcess process_sdcompare;
QString command_sdcompare;
QStringList args_sdcompare;

command_sdcompare = "diff";
args_sdcompare << "Filename" << "Filename";

process_sdcompare.start(command_sdcompare,args_sdcompare,QIODevice::ReadOnly);
process_sdcompare.waitForFinished();                                        
QString StdOut_sdcompare = process_sdcompare.readAllStandardOutput(); //Reads standard output
QString StdError_sdcompare = process_sdcompare.readAllStandardError(); //Reads standard error

if(StdOut_sdcompare.isEmpty())  //the process output is checked here if empty it is a success
    return 1;

我正在运行上面的代码。当我在比较不相似的文本文件后检查错误情况时,isEmpty() 返回false

如何检查QProcess 的执行是否没有错误?

【问题讨论】:

  • 只是一个注释,与你的问题无关:你代码中的cmets 相当没用。它们只是被调用函数的名称,单词之间有空格。最好注释为什么某些东西是这样写的,而不是行中发生的事情,因为这应该从代码中清楚。
  • 关于你的问题:你应该看看进程的exit code

标签: c++ linux qt


【解决方案1】:

我使用QProcess::error() 来查询最后一个错误(用于快速调试),但这是一种“更好”的方法:

// capture any errors (do this before you run the process)
connect(&process_sdcompare, &QProcess::errorOccurred, this, &ThisClass::processError);

然后定义槽:

ThisClass::processError(QProcess::ProcessError error)
{
    qDebug() << "error enum val = " << error << endl;
}

更新

或者使用 Lambda:

// No need to define a slot function...
connect(&process_sdcompare, &QProcess::errorOccurred, [=](QProcess::ProcessError error) 
{ 
    qDebug() << "error enum val = " << error << endl; 
});

【讨论】:

  • 在我看来,如果您连接到 lambda 函数 (Qt 5) 而不必定义插槽,代码可能会更整洁,但除此之外,是的,这是要走的路;O )
  • @TheDarkKnight ehhh...好吧,强迫我写一个 lambda :),我的 lambda defs 仍然有点笨拙,所以请仔细检查它是否正常(我没有开发人员今天附近有电脑)
【解决方案2】:

我认为所有的状态和错误函数对于判断流程执行是否真的成功是毫无用处的。例如,试图执行一个不存在的程序(windows下):

error(): QProcess::ProcessError(FailedToStart)
exitStatus(): QProcess::ExitStatus(NormalExit)
exitCode(): 0
errorString(): "Process failed to start: Das System kann die angegebene Datei nicht finden."

如果进程实际执行成功:

error(): QProcess::ProcessError(UnknownError)
exitStatus(): QProcess::ExitStatus(NormalExit)
exitCode(): 0
errorString(): "Unknown error"

所以我认为“未知错误”不是成功的指标。

我认为的解决方案可能是这样的:

QProcess *m_proc = new QProcess(this);
bool errorOccured = false;
QProcess::ProcessError procError;
QObject::connect(m_proc, &QProcess::errorOccurred, [&](QProcess::ProcessError error)
{
    procError = error;
    errorOccured = true;
});

m_proc->start(...);

【讨论】:

    【解决方案3】:

    waitForFinished 返回时,它会返回一个大致表示成功的bool。按照 Karsten 的建议,您可以使用 QProcess::exitCode 检查实际成功或失败。

    【讨论】:

      【解决方案4】:

      这就是你使用QProcess的方式

      QProcess process_sdcompare;
      QStringList args_sdcompare;
      args_sdcompare << "Filename" << "Filename";    
      process_sdcompare.setProgram("diff");
      process_sdcompare.setArguments(args_sdcompare);
      process_sdcompare.start();
      if (process_sdcompare.waitForStarted() && process_sdcompare.waitForFinished()) {
        QString StdOut_sdcompare = process_sdcompare.readAllStandardOutput();   
        QString StdError_sdcompare = process_sdcompare.readAllStandardError();
      
        if(StdOut_sdcompare.isEmpty())
            return 1;
        }
      }
      

      【讨论】:

      • 这是一个很好的代码示例 :) - 但我认为它并不能真正回答用户的问题(如何检查 QProcess 执行是否有错误)