调用accept,done或close后,模态对话框挂起

时间:2016-10-25 08:51:23

标签: c++ qt dialog modal-dialog qdialog

我有一个名为的模态对话框:

qDebug() << "Creating LoginStatusDialog";
dlgConnectStatus = new LoginStatusDialog(login, key, auth);
qDebug() << "Done LoginStatusDialog, setting modal";
dlgConnectStatus->setModal(true);
qDebug() << "Done setting modal, executing";
int res = dlgConnectStatus->exec();
qDebug() << "dlgConnectStatus result = " << QString::number(res);

//see below for debug info and output

这会调用一个自定义构造函数,它在下面执行

LoginStatusDialog.cpp(摘录):

LoginStatusDialog::LoginStatusDialog( QString _login,  QString _key, QString *_auth_tok, QWidget *parent) :
    QDialog(parent), ui(new Ui::LoginStatusDialog), login(_login), key(_key)
{
    ui->setupUi(this);
    Return_Object = new ReturnObject(ReturnCode::netcon_LoginSuccess, QString(""));
    if (Return_Object->getCode() == ReturnCode::netcon_LoginSuccess) {
        qDebug() << "pre close";
        close();
        //accept - hangs
        //done(0); - hangs
        qDebug() << "post close";
    }
}

LoginStatusDialog标题

#ifndef LOGINSTATUSDIALOG_H
#define LOGINSTATUSDIALOG_H

#include <QDialog>
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
#include <thread>

#include "returnobject.h"
#include "datamanager.h"

namespace Ui {
class LoginStatusDialog;
}

class LoginStatusDialog : public QDialog
{
    Q_OBJECT

public:
//    explicit LoginStatusDialog(QWidget *parent = 0);
    LoginStatusDialog( QString _login,  QString _key, QString *_auth_tok, QWidget *parent = 0);
    ~LoginStatusDialog();

private:

    Ui::LoginStatusDialog *ui;
    QString login, key;

    ReturnObject *Return_Object;

    void initGui();
};

#endif // LOGINSTATUSDIALOG_H

调试信息

Debugging starts
Creating LoginStatusDialog
pre close
post close
Done LoginStatusDialog, setting modal
Done setting modal, executing
//remains open

通过一些研究,有几个SO帖子提到使用done()close()accept()关闭对话框

使用CONNECT()使用close()方法关闭对话框,但尝试手动关闭它并没有成功。

建议使用计时器任务,但这似乎不是关闭对话框的实际方法。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这似乎更像是一般设计问题。如果你真的希望这样做,你可以使用计时器。但是简单的重新设计可能会更有帮助。

如果您只想在发生错误时显示对话框,为什么不仅仅显示它呢?

Return_Object = new ReturnObject(ReturnCode::netcon_LoginSuccess, QString(""));
if (Return_Object->getCode() != ReturnCode::netcon_LoginSuccess) 
{
    dlgConnectStatus = new LoginStatusDialog(Return_Object);
    dlgConnectStatus->setModal(true);
    int res = dlgConnectStatus->exec();
    //...
}

这样,负责仅显示信息的对话框才会执行此操作。显示登录错误。这似乎是创建对话框然后立即关闭它的设计缺陷(特别是考虑到好的情况应该是你的默认情况)。

如果Dialog正在做额外的事情,你应该考虑在一个旨在显示信息的类中真正需要多少代码。

答案 1 :(得分:0)

从构造函数调用close是错误的,导致对话框在构造函数结束后显示,因此您的检查无法关闭对话框,但未显示。你需要在{in} QDialog::showEvent之后调用close。或者,就像我在你的第一个主题中说的那样 - 你可以使用定时器循环。