Michael Vincent
Michael Vincent

Reputation: 1660

Using QProgressDialog properly

I am using QProgressDialog to show the progress of loading data from a database in a QTreeView. I use signals and slots to send the number of records and the current record. This is the slot code:

void MainWindow::loadDataUpdate(int value, int max)
{ 
    if ((max > 0) && (value == 0))
    {
        m_progressDialog = new QProgressDialog("Warming up - please wait ...            ", "Cancel", value, max , this);

        m_progressDialog->setMinimumDuration(2);
        m_progressDialog->setWindowModality(Qt::WindowModal);
        m_progressDialog->setAttribute(Qt::WA_DeleteOnClose);
        m_progressDialog->setCancelButton(0);
        m_progressDialog->setWindowTitle( this->windowTitle()  );
    }
    if ((value == max) && (max > 0) )
    {
        m_progressDialog->setValue(m_progressDialog->maximum());
        return;
    }
    m_progressDialog->setValue(value);
}

m_progressDialog is declared in the .h file as:

QProgressDialog* m_progressDialog;

So, sending a zero value and a max value creates the dialog and sets it up.

The problem I have is that if the user closes the ProgressDialog form by clicking on the cross in the top right corner or by using alt-F4, an error occurs. This is presumably because I am using Qt::WA_DeleteOnClose.

What I'd like to do is detect that the dialog has been closed and open it again, or offer to close the whole application or continue.

How can I test if the progress dialog has been closed?

Or prevent it being closed?

Upvotes: 0

Views: 1611

Answers (1)

SingerOfTheFall
SingerOfTheFall

Reputation: 29986

QProgressDialog offers a cancelled signal for that. You can connect to it, and either show the dialog back, or do whatever else you want to.

So what you need to do is to create an appropriate slot, and connect it to the signal:

connect(m_progressDialog, &QProgressDialog::canceled, this, &MainWindow::onDialogCanceledSlot);

<..>
//add a slot to your window class:
class MainWindow
{
public slots:
    void onDialogCanceledSlot()
    {
        m_progressDialog->show();//for example.
    }
}

if you just want to show it back, you can use a lambda:

connect(m_progressDialog, &QProgressDialog::canceled, [&](){
    m_progressDialog->show();
});

Note that you still can't do that while using WA_DeleteOnClose (since the dialog gets deleted anyway), so I would advise you to avoid setting WA_DeleteOnClose, and instead to store your dialog in a QScopedPointer. This way you will be able to reuse it (without re-creating), and it will be properly deleted when your MainWindow dies.

Upvotes: 2

Related Questions