完全没有必要使用单独的线程来启动进程。
确保在应用程序终止时终止子进程的最简单方法是
QProcess * p = new QProcess(....);
connect(qApp, SIGNAL(aboutToQuit()), process, SLOT(terminate()));
请参阅下面的完整示例。
这种误解就像一种疾病一样传播开来,认为线程是解决每个人问题的方法。我的观察是,在带有标签的 10 个帖子中,有 9 个Qt
使用线程是不必要的,并且是不了解问题的结果。
我的规则是:如果你认为你需要使用线程,试着解释它,如果只是在你的脑海里,以说服你的同事。完成此操作后,检查您引用来支持您的论点的所有事实是否确实正确。在许多情况下,它们不是。
下面的示例代码不会捕获 Unix 信号,因此——正如您在 Linux 和 OS X 上会注意到的那样——它只会终止直接后代进程,而不是可能从它启动的任何后续进程。你需要处理 Unix 信号来解决这个问题。
//main.cpp
#include <QApplication>
#include <QPushButton>
#include <QProcess>
class Launcher : public QObject
{
Q_OBJECT
int n;
QProcess * process;
signals:
void setDisabled(bool);
public slots:
void launch() {
QStringList args;
args << QString::number(n);
process = new QProcess(this);
process->start(QCoreApplication::applicationFilePath(), args);
connect(qApp, SIGNAL(aboutToQuit()), process, SLOT(terminate()));
emit setDisabled(true);
}
public:
Launcher(int no) : n(no), process(0) {}
~Launcher() {
if (process) {
process->terminate();
process->waitForFinished();
}
}
};
int main(int argc, char ** argv)
{
QApplication a(argc, argv);
int n = 0;
if (argc > 1) n = QByteArray(argv[1]).toInt();
Launcher launcher(n+1);
QPushButton spawn(QString("Spawn #%1").arg(n));
launcher.connect(&spawn, SIGNAL(clicked()), SLOT(launch()));
spawn.connect(&launcher, SIGNAL(setDisabled(bool)), SLOT(setDisabled(bool)));
spawn.show();
return a.exec();
}
#include "main.moc"