您好。在我的应用程序中,我在MainWindow的构造函数完成之前运行QDialog。根据此QDialog中的用户输入,我想关闭应用程序。
我无法调用qApp->quit()
或qApp->exit(int retcode = 0)
,因为QApplication事件循环尚未启动。有没有办法可以强制MainWindow退出?或者可能要等到它完全加载才退出?
我设法让它工作但我不明白为什么。这是我目前的QDialog的.cpp:
QFileInfo checkConfig(configPath);
if(!checkConfig.exists() || !checkConfig.isFile())
{
qDebug() << "Sair!";
qApp->quit();
//qApp->exit(1);
//QTimer::singleShot(0, qApp, &QCoreApplication::quit);
QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
}
使用QTimer::singleShot(0, qApp, &QCoreApplication::quit)
,QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection)
,qApp->quit()
或qApp->exit(1)
没有做任何事情。
但是,出于某种原因,使用(qApp->quit()
或qApp->exit(1)
)和(QTimer::singleShot(0, qApp, &QCoreApplication::quit)
或QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection)
)有效!
我觉得使用这个解决方案后来可以回来咬我的屁股,因为我不知道它是如何工作的。有没有人有更好的解决方案或解释?
单独调用QTimer::singleShot(0, qApp, &QCoreApplication::quit)
并不是为我关闭申请。虽然,我第二次通过该功能,它确实关闭。 QTimer::singleShot()
采用重新实施的QDialog::reject
方法。在关闭之前,我会显示QMessageBox
。任何此类操作都可能会干扰QTimer
?
我运行了示例@ user3606329 show。它确实有效。我进一步前进了一步,并使用了本节中其他程序的QDialog
。它确实没有用。问题出在我的QDialog
?以下是整个reject
方法:
void Configuracao::reject()
{
QFileInfo checkConfig(configPath);
if(!checkConfig.exists() || !checkConfig.isFile())
{
QMessageBox::critical(this,"Erro na configuração","Erro na criação do aquivo config.ini.\n"
"O programa será finalizado!");
qDebug() << "Sair!";
//qApp->quit();
//qApp->exit(1);
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
//QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
}
}
我决定使用QDialog
创建另一个QTimer::singleShot
和 ONLY 重新实施拒绝方法。它仍然没有奏效。第一次调用拒绝时,它经历了QTimer::singleShot
并且什么也没做(甚至没有关闭对话框)。第二次,它关闭了对话框并关闭了应用程序。有什么想法吗? (以下代码)
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dialog.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
Dialog *conf;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
conf = new Dialog(this);
conf->exec();
}
MainWindow::~MainWindow()
{
delete ui;
}
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
protected:
void reject();
};
#endif // DIALOG_H
dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include <QTimer>
#include <QDebug>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::reject()
{
QTimer::singleShot(0, qApp, []() {
qDebug() << "QTimer done";
QCoreApplication::quit();
});
}
main.cpp中:
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
qDebug() << "Event loop started";
return a.exec();
}
输出:
QTimer done //first click on "close window"
Event loop started //first click on "close window"
QTimer done //second click on "close window"
答案 0 :(得分:2)
#include <QShowEvent>
#include <QDebug>
...
protected:
...
void showEvent(QShowEvent *event);
...
private:
...
bool init_check = false;
...
void MainWindow::showEvent(QShowEvent *event){
qDebug() << "QShowEvent" << init_check;
if(!init_check){
init_check = true;
bool err = true;
if(err){
qDebug() << "Closing app";
exit(EXIT_FAILURE);
}
}
}
答案 1 :(得分:2)
以下代码
QTimer::singleShot(0, qApp, &QCoreApplication::quit)
将队列quit()并在启动事件循环时执行它。不需要其他任何东西。你可以看看这个小例子:
#include "mainwindow.h"
#include <QApplication>
#include <QTimer>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QTimer::singleShot(0, qApp, []() {
qDebug() << "Event loop started";
QCoreApplication::quit();
});
return a.exec(); // QCoreApplication::quit() is executed after the call
}
在事件循环开始之前运行以下代码
qApp->quit() or qApp->exit(1)
对您的申请不会有任何影响。
<强> 恢复 强>
您似乎没有在编辑器中正确放置代码,或者您在问题中遗漏了重要部分。我建议您使用上面的代码示例创建一个简单的应用程序。