介绍

你好在我的应用程序中,我在MainWindow的构造函数完成之前运行QDialog。根据此QDialog中的用户输入,我要关闭该应用程序。

问题

由于QApplication事件循环尚未开始,因此我无法调用qApp->quit()qApp->exit(int retcode = 0)。有没有一种方法可以强制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吗?

编辑2

我运行了示例@ user3606329展示。确实可以。我进一步走了几步,并在此程序的另一个程序中使用了自己的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);
    }
}

编辑3

我决定再创建一个QDialog,然后仅创建QTimer::singleShot重新实现拒绝方法。它仍然没有用。第一次调用拒绝时,它经历了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"

最佳答案

以下代码

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)

不会对您的应用程序产生任何影响。

简历

您似乎没有正确地将代码放置在编辑器中,或者在问题中遗漏了重要部分。我建议您使用上面的代码示例创建一个简单的应用程序。

关于c++ - Qt-从QDialog关闭程序(在MainWindow完全加载之前),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49562236/

10-09 00:05