Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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.
    QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
    

    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?


  • Qt Champions 2019

    @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:

    @autoreleasepool
    {
        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

    Hi,

    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