QProcess::terminate() 不适用于简单的 Qt 应用程序作为 Windows XP 下的子进程

QProcess::terminate() doesn't work with simple Qt app as child process under Windows XP

本文关键字:Windows XP 子进程 应用程序 Qt 不适用 适用于 QProcess 简单 terminate      更新时间:2023-10-16

首先,我将从QProcess对象启动的简单Qt应用程序:

#include <QtGui>
class LOLProcess : public QMainWindow {
    Q_OBJECT
public:
    LOLProcess(QWidget *parent = 0);
    ~LOLProcess();
protected:
    void closeEvent(QCloseEvent *);
};
LOLProcess::LOLProcess(QWidget *parent) : QMainWindow(parent) {
}
LOLProcess::~LOLProcess() {
    qDebug() << "~LOLProcess()";
}
void LOLProcess::closeEvent(QCloseEvent *) {
    qDebug() << "closeEvent()";
}
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    LOLProcess w;
    w.show();
    return a.exec();
}

现在,带有 QProcess 对象的 Qt 应用程序:

#include <QtGui>
class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    QProcess process;
public slots:
    void close_down();
};
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    process.start("../../lolprocess-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Release/release/lolprocess.exe");
    QTimer::singleShot(3000, this, SLOT(close_down()));
}
void MainWindow::close_down() {
    process.terminate();
    while (!process.waitForFinished(500)) {
    qDebug() << process.readAllStandardError();
    qDebug() << process.readAllStandardOutput();
    }
    qDebug() << process.waitForFinished(5000);
    qDebug() << (process.state() == QProcess::Running);
}
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QDir::setCurrent(QCoreApplication::applicationDirPath());
    MainWindow w;
    w.show();
    return a.exec();
}

行为:terminate() 导致子进程的窗口消失(并从 XP 任务栏中消失),但进程仍在根据任务管理器运行。while (!process.waitForFinished(500))永远循环,因为 QProcess 对象永远不会发出 finished()。令人惊讶的是,我从子进程中没有得到任何关于 stdin 或 stderr 的信息(它只打印QProcess::readAllStandard...()调用的空字符串),这似乎很奇怪,因为子进程的顶部窗口关闭让我认为 closeEvent() 是在子进程中调用的。

使用 QProcess::kill() 终止子进程是有效的,但我不想使用它,因为它没有给子进程在退出之前清理的机会。

有趣的是,同样的代码在Qt 4.7.4和OS X 10.6.x下正常工作 - terminate()会导致子进程干净地退出,所以我不确定我在XP下做错了什么。谢谢。

现在试试:

#include <QtGui>
class LOLProcess : public QMainWindow {
    Q_OBJECT
public:
    LOLProcess(QWidget *parent = 0);
    ~LOLProcess();
protected:
    void closeEvent(QCloseEvent *);
public slots:
    void lastWindowClosed();
};
LOLProcess::LOLProcess(QWidget *parent) : QMainWindow(parent) {
}
LOLProcess::~LOLProcess() {
    qDebug() << "~LOLProcess()";
}
void LOLProcess::closeEvent(QCloseEvent *) {
    qDebug() << "closeEvent()";
}
void LOLProcess::lastWindowClosed (){
    QApplication::quit();
}
int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    LOLProcess w;
    QObject::connect(&a, SIGNAL(lastWindowClosed()), &w, SLOT(lastWindowClosed()));
    w.show();
    return a.exec();
}

这应该是没有必要的。qt中似乎有一些非常奇怪的怪癖/错误-当我有更多时间时,我会进一步调查。