Solved 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 UII'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 theQApplication::exec()
statement. The macOS framework running the UI is self-contained - deployed bymacdeployqt
with a little bit of tuning, since the latter didn't introduce the correctLC_RPATH
s 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 withQtConcurrent
and afterward withstd::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?
-
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 theLC_RPATH
s 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 thatQGuiApplicationPrivate::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 ofQGuiApplicationPrivate
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 usingotool -l
orotool -L
.Would report investigation results.
-
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_RPATH
s inside the library's binary and those of the plug-ins. Thanks for the suggestion. -
Glad you found out and thanks for sharing ?
What was your final solution ?