【问题标题】:Properly using Qt QProcess正确使用 Qt QProcess
【发布时间】:2021-06-18 15:17:05
【问题描述】:

我正在考虑使用 QProcess 多次调用命令行应用程序 (gpio)。每次用户点击一个按钮就会发出一个命令。

并且应用程序输出将被监控并重定向到屏幕。代码如下所示。

void Gpio::command(QString argument)
{
//    if(process)
//        delete process;
    process = new QProcess(this);
    connect(process, SIGNAL(started()), this, SLOT(onStart()));
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(readGpio()));
    QString program("gpio");
    QStringList list = argument.split(" ");
    process->start(program, list);
}

问题:我应该delete process吗?这样做我得到了:

QProcess: Destroyed while process is still running.

监控exitCodeexitStatus 我看到他们总是0

这个问题更多地关注QProcess的正确使用,而"QProcess and shell : Destroyed while process is still running"关注具体错误。

【问题讨论】:

标签: qt qprocess


【解决方案1】:

由于您不想同时运行多个进程(根据 cmets),因此您无需多次创建/删除 QProcess

gpio.h

QProcess*   m_gpioProcess;

gpio.cpp 文件

Gpio::Gpio(.....),
   .....(),
   m_gpioProcess(new QProcess(this))
{
   m_gpioProcess->setProgram("gpio");

   connect(m_gpioProcess, SIGNAL(started()), this, SLOT(onStart()));
   connect(m_gpioProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinish(int,QProcess::ExitStatus)));
   connect(m_gpioProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readGpio()));
}

void Gpio::command(const QString& args)
{
  if (m_gpioProcess->state() != QProcess::NotRunning) {
    qDebug() << "Process already running, ignoring the request";
    return;
  }

  m_gpioProcess->setArguments(args.split(" "));
  m_gpioProcess->start();
  if (m_gpioProcess->waitForStarted()) {
    qDebug() << "Process started with arguments:" << m_gpioProcess->arguments();
  }
}

如果您想阻止用户多次单击按钮,请考虑按照m_gpioProcess 状态启用/禁用按钮。


对于Qt 4.8,只需删除此行

m_gpioProcess->setProgram("gpio");

还有这一行

m_gpioProcess->setArguments(args.split(" "));

并改变这一行

m_gpioProcess->start();

m_gpioProcess->start("gpio", args.split(" "));

【讨论】:

  • 我认为这是针对Qt5的,我在Qt4上。在 Qt4 中看不到 setProgramsetArguments。有什么办法吗?
  • 所以我得到了QProcess::start: Process is already running。我不想忽略这个请求。我应该等待多长时间才能发出新命令(每个命令几乎立即返回)?
  • 你有finished(int,QProcess::ExitStatus) 信号来监控这个。您应该能够在此之后立即创建新命令。
  • 您的意思是在exitCode=0exitStatus=0 之后我应该能够再次调用start(使用不同的参数)?我正在这样做并得到QProcess::start: Process is already running。也许必须在这两个步骤之间做点什么?
  • 可能会问发出完成后会发生什么以防止对象被删除?我想阻止我重新开始的同一件事也阻止我删除对象。
【解决方案2】:

好吧,我似乎在拨打start 之后忘记了process-&gt;waitForFinished();。这似乎解决了问题。

【讨论】:

    【解决方案3】:

    添加以下代码可能会有所帮助:

    process->close();
    

    【讨论】:

    • 您能补充更多解释吗?这段代码有什么作用?你在哪里添加这行代码?