【问题标题】:Checking whether qprocess has finished检查 qprocess 是否已完成
【发布时间】:2016-07-06 19:27:29
【问题描述】:

我必须检查我的过程是否已完成,我需要将其转换为 bool,因为我想要你 if。
在 MainWindow.h 我创建了一个对象

QProcess *action;

在 mainwindow.cpp 中

void MainWindow:: shutdown()
{
action=new QProcess(this);
action->start("shutdown -s -t 600");
//and now I want to use if
if (action has finished)
{
  QMessageBox msgBox;
  msgBox.setText("Your computer will shutdown in 1 minute.");
  msgBox.exec();
}

【问题讨论】:

  • waitForFinished 函数或finished 信号在完成后立即通知有什么问题?
  • @JamesAdkison 这两个建议不属于同一个句子。 waitForFinished 是一种阻止方法,使 UI 无响应。它不适用于交互式线程。
  • @KubaOber 我不听你的评论。第一个(在or之前)是一个阻塞函数,第二个(在or之后)是一个使用Qt信号槽机制的非阻塞解决方案。
  • @JamesAdkison 建议使用waitForFinished 方法或finished 信号就像是在说“有一个苹果。或者一个同温层堡垒。”。在极少数情况下,waitFor 方法是合适的。大多数尝试在 SO 问题(或答案)中使用它的人都不应该这样做。
  • @KubaOber 好的,我明白你的意思。需要明确的是,我并不是说它适合他们的用例(这肯定出现 shutdown 是在主线程的上下文中执行的)。我本质上是在问“为什么这个(阻塞解决方案)或(非阻塞解决方案)对你不起作用?”

标签: c++ qt qprocess


【解决方案1】:

您应该连接到进程的finished 信号。只要流程完成,您的代码就会被调用。例如

// https://github.com/KubaO/*n/tree/master/questions/process-finished-msg-38232236
#include <QtWidgets>

class Window : public QWidget {
   QVBoxLayout m_layout{this};
   QPushButton m_button{tr("Sleep")};
   QMessageBox m_box{QMessageBox::Information,
            tr("Wakey-wakey"),
            tr("A process is done sleeping."),
            QMessageBox::Ok, this};
   QProcess m_process;
public:
   Window() {
      m_layout.addWidget(&m_button);
      m_process.setProgram("sleep");
      m_process.setArguments({"5"});
      connect(&m_button, &QPushButton::clicked, &m_process, [=]{ m_process.start(); });
      connect(&m_process, (void(QProcess::*)(int))&QProcess::finished, [=]{ m_box.show(); });
   }
};

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   Window window;
   window.show();
   return app.exec();
}

【讨论】:

  • 当我想使用这个 txt.wklej.se/37d7 时,我收到一个错误,传递 'const QMessageBox' 作为 'void QWidget::show()' 的 'this' 参数丢弃限定符 [-fpermissive]
  • @MichałUrban 您需要了解代码的含义,您不能只是复制粘贴并期望它偶然起作用。您的代码无法工作有两个原因:1. 消息框将在 shutdown 方法返回后立即被破坏,以及 2. 您无法在 lambda 中按值捕获 QObject 实例。在答案中,按值捕获适用于 this 指针,因为这是 lambda 正在捕获的唯一变量。如果它对您来说更明显,您可以使用std::bind(&amp;QMessageBox::show, m_box)。我在答案中显示的代码与您的粘贴之间存在重要差异。
  • 请注意,我会附加到完成,但如果出于某种原因您想要忙于等待,您也可以询问进程的状态。 doc.qt.io/qt-5/qprocess.html#state