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

Show Qt widget-based UI from a Qt-based framework called by a non-Qt-based application on macOS



  • Hello, all.

    The usage scheme:

    Non-Qt-based application (exe/app)
    -> loads my Qt-based library (dll/framework)
    -> creates Qt-based UI

    I've attempted to run Qt widget-based UI in a Qt-based dll on Windows, where the latter is used by non-Qt-based application and it works:

    void showQtUi()
    {
        int argsCount = 0;
        QApplication a{ argsCount, Q_NULLPTR };
        QWidget w;
        w.show();
        a.exec();
    }
    

    Running this code on macOS results in the following crash of the calling application:

    Crashed Thread:        0  CrBrowserMain
    Dispatch queue:        com.apple.main-thread
    
    Exception Type:        EXC_CRASH (SIGABRT)
    Exception Codes:       0x0000000000000000, 0x0000000000000000
    Exception Note:        EXC_CORPSE_NOTIFY
    
    Application Specific Information:
    abort() called
    
    Application Specific Signatures:
    {..., platform:MAC, os_ver:10.14.6, ... (64-Bit app), error_reporting_mode:3}
    
    Thread 0 Crashed:: CrBrowserMain  Dispatch queue: com.apple.main-thread
    0   libsystem_kernel.dylib        	0x00007fff79cea2c2 __pthread_kill + 10
    1   libsystem_pthread.dylib       	0x00007fff79da5bf1 pthread_kill + 284
    2   libsystem_c.dylib             	0x00007fff79c546a6 abort + 127
    3   org.qt-project.QtCore         	0x0000000163b64529 0x163b4c000 + 99625
    4   org.qt-project.QtCore         	0x0000000163b65c74 QMessageLogger::fatal(char const*, ...) const + 202
    5   org.qt-project.QtGui          	0x00000001635823d9 QGuiApplicationPrivate::createPlatformIntegration() + 7193
    6   org.qt-project.QtGui          	0x00000001635823fb QGuiApplicationPrivate::createEventDispatcher() + 27
    7   org.qt-project.QtCore         	0x0000000163d441af QCoreApplicationPrivate::init() + 1599
    8   org.qt-project.QtGui          	0x000000016357cb59 QGuiApplicationPrivate::init() + 57
    9   org.qt-project.QtWidgets            0x0000000162fa7ada QApplicationPrivate::init() + 26
    10  MyLibrary.                          0x0000000162f1044d showQtUi() + 285
    

    The crash comes from the instantiation of QApplication where I don't know what happens but for sure still, the Qt's event loop is not run because it does at the QApplication::exec() statement. The macOS framework running the UI is self-contained - deployed by macdeployqt with a little bit of tuning, since the latter didn't introduce the correct LC_RPATHs into the library's binary and thus the dependent Qt frameworks were not found. The used Qt version is the latest 5.x one at the current moment - 5.15.2 clang 64-bit where tests with Qt 6 are pending. The used macOS version is 10.14.6 (Mojave). Would test it on Catalina or Big Sur. Haven't tried creating the simplest macOS GUI app which would call a Qt framework running widget-based UI due to time restraints.
    Also, I've tried running this code on macOS with QtConcurrent and afterward with std::thread (so that it is not Qt-related) on another thread so that Qt's UI and event-loop doesn't somehow interfere with the native one established by the calling non-Qt application but in all scenarios the application crashed.

    Any ideas how to run the Qt UI on macOS?


  • Lifetime Qt Champion

    Hi,

    Can you get the debugger to show you more information ?
    I am wondering if it could be the cocoa plugin being not found.



  • @SGaist :
    " Can you get the debugger to show you more information ?


    I am trying to but the debugger exists immediately after I try to attach to the running application:

    19:53:24: Debugging starts
    19:53:26: Debugging has finished // 2 secs
    

    Attempting to "Start and Debug External Application..." instead of attaching to an already started one results in the same issue but with greater delay between the launching and closing of the debugger:

    20:00:30: Debugging starts
    20:00:42: Debugging has finished // 12 secs
    

    This way the application even doesn't startup.

    " I am wondering if it could be the cocoa plugin being not found.


    A suggestion I think in the most probable direction. What I forgot to mention is that I am afraid that there could be a chance that the Qt plug-ins are not well deployed by macdeployqt. Presumably the LC_RPATHs inside them could be problematic and not only - the Qt frameworks could somehow be unable to find the plug-ins. So you gave a suggestion in the same direction. I should have thought that QGuiApplicationPrivate::createPlatformIntegration() + 7193 should actually have to do with glueing the platform abstraction layer with the specific platform implementation.

    Will see what's on line 7193 in the file containing the implementation of QGuiApplicationPrivate and will check the plug-ins again - whether they are visible by the Qt frameworks and vice versa. Problem is that only the documentation and the source can speak something about those dependencies since they are loaded at runtime rather than being set as explicit dependencies in the Qt frameworks' binaries - by looking at them using otool -l or otool -L.

    Would report investigation results.


  • Lifetime Qt Champion

    You can also start your application with the QT_DEBUG_PLUGINS environment variable set to 1. It should print on the terminal lots of information with regard to plugin loading (or failure to load).



  • @SGaist, found the reason: another library loaded by the non-Qt application was also making use of Qt and there was a clash of loaded Qt versions into the memory. This was explicitly seen as dumps upon starting the application from the command-line. Tried your suggestion as well but no wrong loaded plug-ins message was output. This could be due to the fact that I've already fixed some LC_RPATHs inside the library's binary and those of the plug-ins. Thanks for the suggestion.


  • Lifetime Qt Champion

    Glad you found out and thanks for sharing ?

    What was your final solution ?


Log in to reply