mainwindow.h:
#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行中的close(),第1行中的close()将关闭窗口并使应用程序继续运行。
如果我注释掉第1行中的close(),则第2行中的close()会关闭窗口并结束应用程序。
为什么这种行为存在差异?
答案 0 :(得分: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有一个新的连接语法允许使用lambdas和QtConcurrent已经能够使用lambdas QTimer或更具体的QTimer :: singleShot()缺乏这两者。 为QTimer :: singleShot()提供函数指针语法和lambda支持也很方便(也是一致的)。
修改2
更准确地说,当您调用QMainWindow::close()
时,会引发QMainWindow::closeEvent(QCloseEvent *)
事件,通常应该在当前事件循环中处理它。由于在调用close
时没有事件循环,因此不会捕获此事件,也不会导致应用程序退出。