How to block the 'native close button' of a QProgressDialog on OS X?

550 Views Asked by At

I'm creating a QProgressDialog as follows:

QProgressDialog progressDialog = new QProgressDialog(tr("Calculating..."), NULL, 0, 100, this);
progressDialog->setAutoClose(true);
progressDialog->setValue(0);
progressDialog->setWindowTitle(tr("Calculate Weights"));
progressDialog->setWindowFlags(progressDialog->windowFlags() & ~Qt::WindowCloseButtonHint);
progressDialog->show();

Note that I'm using the Qt::WindowCloseButtonHint flag to disable the 'native close button'. It seems to work well on Windows but not on OS X (on OS X the close button is still available and the user can close the QProgressDialog).

I have also tested with other flags (e.g. Qt::WindowSystemMenuHint, Qt::WindowTransparentForInput) but none have solved my problem.

Sure I can use the Qt::FramelessWindowHint flag to remove the 'entire border of the window' but it is not my objective, since I just want to disable the close button.

What window flag can I use to disable/block the QProgressBar close button on OS X?

2

There are 2 best solutions below

0
On

As mentioned by @phyatt it was solved by using the following combination of flags:

progressDialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);

As answered here: Qt hide minimize, maximize and close buttons

3
On

Subclass the dialog, and re-implement QCloseEvent.

http://doc.qt.io/qt-5/qcloseevent.html

In that you can stop and ignore, or respond with a "are you sure" kinds of things.

See http://doc.qt.io/qt-5/qtwidgets-mainwindows-application-example.html#close-event-handler

// in your MyProgressDialog.h
protected:
    void closeEvent(QCloseEvent *event) override;

// In your MyProgressDialog.cpp
void MyProgressDialog::closeEvent(QCloseEvent *event)
{
    //if (maybeSave()) {
    //    writeSettings();
    //    event->accept();
    //} else {
    //    event->ignore();
    //}
    if(event->spontaneous())// this might work, or you can just use an else on the next if statement instead.
        event->ignore();
    else if(m_progress == 100 || m_isDone)
        event->accept();
}

Hope that helps.