2013-04-26 1 views
1

mainwindow.h:Почему close() работает только одним способом, а не другим?

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 
    void test(); 

private slots: 
    void on_pushButton_clicked(); 

private: 
    Ui::MainWindow *ui; 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp:

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

void MainWindow::test() 
{ 
    close(); // Line 1 
} 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::on_pushButton_clicked() 
{ 
    close(); // Line 2 
} 

main.cpp:

#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    w.test(); 

    return a.exec(); 
} 

Если я закомментируйте близко() в строке 2, закрывающий () в строке 1 закрывает окно и оставляет приложение запущенным.

Если я закрою строку close() в строке 1, функция close() в строке 2 закрывает окно и завершает приложение.

Почему существует такая разница в поведении?

ответ

0

Причина этого заключается в том, что w.test() вызова вызывается до Начато (a.exec()) цикл событий, поэтому он не вызовет каких-либо другое событие должно произойти, которые могут быть связаны с close() работы QMainWindow.

Во втором подходе ваша close() функция будет вызвана после запуска цикла событий, лучше сказать, в вашем цикле обработки событий (при нажатии на кнопку, вы будете отправлены в on_pushButton_clicked() метод, и close() проинформирует приложение ., что он должен быть положен конец

для запуска test() функции в цикле обработки событий, используйте таймер однократного:

//Qt 4 - in Qt 5, you can work this out without helper slot: 

class MainWindow: public QMainWindow{ 
    //... 
    void test(); 
    //... 
public slots: 
    void testHelper(){ test(); } 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    QTimer::singleShot(0, &w, SLOT(testHelper())); 

    return a.exec(); 
} 

Редактировать

Похоже, что новый синтаксис Qt5 в connect не поможет здесь, чтобы избежать дополнительного слота [1]

Qt5, имеющим новый синтаксис соединения, который позволяет для использования лямбды и QtConcurrent уже неоспоримой способны использовать лямбды QTimer или более в частности QTimer :: singleShot() отсутствует оба. Было бы удобно (и последовательным) иметь синтаксис указателя функции и поддержку лямбда для QTimer :: singleShot().

Edit 2

Чтобы быть более точным, когда вы звоните QMainWindow::close(), QMainWindow::closeEvent(QCloseEvent *) событие возникает, и обычно он должен быть обработан в текущем цикле обработки событий. Поскольку в точке вызова close нет цикла событий, это событие не догнано и ничто не приведет к выходу приложения.

+0

Благодарим вас за объяснение, а не только за решение. – user2317537