7
votes

I have wrote an application in Qt/c++ on OSX. When quitting the app, I'm catching the closeevent to display dialog box

void MainUI::closeEvent (QCloseEvent *event)
{
    if( DeviceUnplugged == false) {
        ExitDialog = new DialogExit;
        ExitDialog->exec();
        if(ExitDialog->result() == QDialog::Accepted) {
            m_device.CloseDevice();
            event->accept();
        }
        else {
            event->ignore();
        }
    }
}

The dialog box is correctly displayed when closing using the red cross or using the menu "quit".

but when I'm closing the app using the right click on the icon in the dock, the dialog box appears twice the close event is called twice.

Any idea why ?

2
What OS? Many Linux DEs have support for docks too.cmannett85
@cmannett85 it's OSXSeb
@Seb Does the second dialog appear if you cancel the first dialog instead of acceptingadnan kamili

2 Answers

3
votes

Looks like this is a QT bug: See: https://bugreports.qt.io/browse/QTBUG-43344

Also had this problem when using qt-5.6_4 ,
In my case it happened when using CMD+Q but didn't happen when using the red x button.

Used a similar patch.
I avoided accept or ignore since this is a bug and I don't think we should "talk to it" :-)

Instead I simply return when called more then once.

static int numCalled = 0;
if (numCalled++ >= 1)
    return;
2
votes

Yes, I think it is normal for Mac, at least I had this in my Qt application, too (only on Mac).

I used the following workaround:

void MainUI::closeEvent (QCloseEvent *event)
{
    if (m_closing)
    {
        event->accept();
        return;
    }
    if( DeviceUnplugged == false) {
        ExitDialog = new DialogExit;
        ExitDialog->exec();
        if(ExitDialog->result() == QDialog::Accepted) {
            m_device.CloseDevice();
            m_closing = true;
            event->accept();
        }
        else {
            event->ignore();
        }
    }
}

By default, boolean variable m_closing should be initialized by false of course in your class. This way second time nothing will be done (processing will be skipped). This worked for me.