2012-05-25 3 views
1

Во-первых, мой простой Qt приложение, которое я начну с QProcess объекта:QProcess :: прекратить() не работает с простой Qt приложения, как дочерний процесс под Windows XP

#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(); 
} 

Теперь Qt приложений с QProcess объекта:

#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(); 
} 

Поведение: оконечный() вызывает окно дочернего процесса исчезать (и с панели задач XP), но процесс все еще работает в соответствии с TaskMan. Цепи while (!process.waitForFinished(500)) навсегда, так как объект QProcess никогда не испускает законченный(). Удивительно, но я ничего не получаю от stdin или stderr от дочернего процесса (он печатает только пустую строку для вызовов QProcess::readAllStandard...()), что кажется странным, потому что закрытие верхнего окна дочернего процесса заставляет меня думать, что в дочернем процессе вызывается closeEvent().

Завершение дочернего процесса с помощью QProcess :: kill() работает, но я не хочу использовать его, потому что он не дает дочернему процессу возможности очистить до выхода.

Интересно, что этот же код работает правильно под Qt 4.7.4, а OS X 10.6.x - terminate() заставляет дочерний процесс выйти из строя, поэтому я не уверен, что я делаю неправильно в XP. Благодарю.

+0

Я думаю, вы должны принять закрытое событие или вызвать метод родительского класса в свой LOLProcess' – Lol4t0

+0

Lol4t0, спасибо за комментарий. Я попытался вставить 'event-> accept();' в closeEvent(), но поведение одного и того же - terminate() не правильно закрывает дочерний процесс. – njahnke

ответ

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(); 
} 

Это не должно быть necesary. Кажется, что-то действительно странное quirk/bug в qt - когда у меня больше времени, я буду исследовать его дальше.

+1

Хорошее обходное решение, но, как вы говорите, это кажется ошибкой. Почему QProcess :: terminate() работает нормально, например. mspaint.exe, но не просто приложение Qt? Возможно, это нужно сообщить. – njahnke

+1

Когда я выясню, что на самом деле неправильно с QT, я увижу, стоит ли сообщать об этом. Пока вам придется жить с этим обходным путем, поскольку у меня мало времени на это. Я уже понял, что событие Quit корректно отправляется в приложение. Почему его увольняют во время обработки, пока не видно ... –

+0

@j_kubik вы когда-нибудь это выясняли? У меня такая же проблема. – Rachael