1

まず、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 タスクバーから) 消えますが、タスクマンによると、プロセスはまだ実行されています。QProcesswhile (!process.waitForFinished(500))オブジェクトは finished() を発行しないため、永久にループします。驚いたことに、子プロセスから stdin または stderr を介して何も取得しません (QProcess::readAllStandard...()呼び出しの空の文字列のみを出力します)。

QProcess::kill() で子プロセスを終了すると機能しますが、終了する前に子プロセスをクリーンアップする機会が与えられないため、使用したくありません。

興味深いことに、この同じコードは Qt 4.7.4 および OS X 10.6.x で正しく動作します - terminate() により子プロセスが正常に終了するため、XP で何が間違っているのかわかりません。ありがとう。

4

1 に答える 1

2

今すぐやってみて下さい:

#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 の本当に奇妙な癖/バグのようです。時間があれば、さらに調査します。

于 2012-05-26T04:05:30.490 に答える