[Solved] Library using Qt 5 with namespace in application using Qt 4 or Qt 5.
-
Qt 5.3 on Mac OS X (Mavericks).
I'm working on a library which shows UI using Qt. The Qt used by this library has its own namespace. This library creates its own QApplication, otherwise, it can't show QWidgets.If this library is used in an application which handles its own UI through [NSApp run], it works fine.
However, if this library is used in an application which uses QApplication::exec in Qt 4.8 or Qt 5.3 without namespace, it doesn't. Panels are brought up, but no input events are handled. This is the case for both panels owned by the calling application and panels owned by the library. (Note: this setup works with Qt 4; a library using Qt 4.8 with namespace in an application which uses Qt 4.8 without namespace. )
I know the QApplication documentation says any GUI application is supposed to have exactly one QApplication, but I don't have any control over what UI technology the calling application is using.
Any suggestions on how to make this work would be greatly appreciated.
-
Hi and welcome to devnet,
Just to be sure I understand you correctly: are you trying to run an application which should load two different libraries, one built with Qt 4 and one with Qt 5 ?
-
Hi and welcome to devnet,
Just to be sure I understand you correctly: are you trying to run an application which should load two different libraries, one built with Qt 4 and one with Qt 5 ?
@SGaist
Hi and thank you,not exactly. The application is using Qt 5 without namespace, or Qt 4, or any other framework, and the library which uses Qt 5 with a namespace. So the appliction as a whole will end up loading its own Qt 4/Qt 5/..., one instance of 'my' library and the Qt 5 with namespace that comes with 'my' library.
(Note: At the moment, I'm investigating if this patch may help.)
-
Qt 5.3 on Mac OS X (Mavericks).
I'm working on a library which shows UI using Qt. The Qt used by this library has its own namespace. This library creates its own QApplication, otherwise, it can't show QWidgets.If this library is used in an application which handles its own UI through [NSApp run], it works fine.
However, if this library is used in an application which uses QApplication::exec in Qt 4.8 or Qt 5.3 without namespace, it doesn't. Panels are brought up, but no input events are handled. This is the case for both panels owned by the calling application and panels owned by the library. (Note: this setup works with Qt 4; a library using Qt 4.8 with namespace in an application which uses Qt 4.8 without namespace. )
I know the QApplication documentation says any GUI application is supposed to have exactly one QApplication, but I don't have any control over what UI technology the calling application is using.
Any suggestions on how to make this work would be greatly appreciated.
I've marked this as solved.
The reason why it doesn't work in Qt 5 are a number of missing Objective-C namespace prefixes in qcocoaapplication.mm that used to be present in Qt 4.8.
-
Can you point the problematic parts ?
-
I'm not an Objective C developer, so I'm probably interpreting some things wrongly, but this is what I see happening:
The calling application sets a QNSApplication as NSApp as part of the creation of a QGUIApplication. This QNSApplication doesn't have a namespace.
The library which uses QT 5 with namespace creates a QGUIApplication as well. Part of this creation is calling
qt_redirectNSApplicationSendEvent
(qcocoaappliction.mm).if ([NSApp isMemberOfClass:[QNSApplication class]])
returns false (not sure why, as it is a QNSApplication), so it callsqt_cocoa_change_implementation
(qcocoaintrospection) to useqt_sendEvent_replacement
(no namespace) forsendEvent
.
WhensendEvent
is called with an event from the library, it's redirected toqt_sendEvent_replacement
(no namespace), which redirects it to the original. This turns out to beqt_sendEvent_original
(no namespace), which ignores signals.If the replacements are namespaced, the original handler is not
qt_sendEvent_original
, I suspect it's the real original of NSApplication instead.(I'll try to make a patch.)
(Edit: it'll look very much like this one.) -
You should consider submitting to code review
-
Very good ! :)