⚠️ Forum Maintenance: Feb 6th, 8am - 14pm (UTC+2)

macOS: how to show NSPanel after a qdialog has been closed?

  • I need to show an NSPanel (so using some cocoa code) after a qdialog has been closed. When doing so my NSPanel is shown but immediately dismissed.
    I looked at qcocoafiledialoghelper.mm to see how it's done there and found the following promising piece of (documented) code:

    // Call processEvents in case the event dispatcher has been interrupted, and needs to do
    // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
    // close down during the cleanup.
    qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);

    But unfortunately that doesn't help in my case.
    There's a second call in qcocoafiledialoghelper.mm before the native panel is shown:

    // Make sure we don't interrupt the runModal call below.

    but that's one I can't call from my code as it uses some Qt internal private stuff.

    Any ideas on how to get this working?

  • Lifetime Qt Champion

    @gvanvoor said in macOS: how to show NSPanel after a qdialog has been closed?:

    When doing so my NSPanel is shown but immediately dismissed

    Can you show your code?
    Sounds like your NSPanel is going out of scope because it's a local variable (just an idea).

  • Not going out of scope:

        MyPanel * thePanel = [ [ MyPanel alloc ] init ];
        qApp->processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers );
        auto theResponse = [ thePanel runModal ];
        if( theResponse == NSModelResponseOK )

    the runModel call returns immediately (while it should be blocking) and theResponse == NSModalResponseStop.

  • Lifetime Qt Champion


    You need to provide an MRE so people can test your code on their own to help debug it.

  • @SGaist I'm assuming MRE stands for a minimal code example that exhibits the problem?

  • I wasn't able to reproduce the problem in a minimal example, but after a lot of digging I finally found the culprit: a worker thread is invoking QCoreApplication::postEvent which somehow causes my panel to close.

  • Lifetime Qt Champion

    Glad you found out and thanks for sharing !

    What event did you post ?

  • @SGaist A custom event. I don’t know if that gets sent through the Cocoa event loop, but I guess it does and assume Cocoa stops the modal panel to be able to process the event in the main event loop.

Log in to reply