Ich muss eine Qt GUI von einer DLL starten, die DLLStart
und DLLStop
anzeigt. Der normale Ansatz (.exe) in main lautet wie folgt:
Das Problem ist der blockierende a.exec()
Aufruf, da in der DLL DLLStart
sofort zurückkehren muss (siehe unten). Irgendeine Abhilfe für dieses? Anmerkung: Die Frage ist eine Gemeinsamkeit mit " Hinzufügen einer Qt-GUI zu" eine dynamische Bibliothek ", aber es ist kein genaues Duplikat.
Eine Möglichkeit unter Windows besteht darin, QApplication
in einem separaten QThread
zu starten. Es ist nicht portierbar - unter OS X funktioniert es nicht (ich forsche nach einer Lösung).
Aber Sie brauchen keinen separaten Thread. Wenn Sie Ihren Code in eine laufende Anwendung injizieren, hat er bereits eine Ereignisschleife. Sie müssen nur ein globales QApplication
-Objekt erstellen, und Sie sind fertig. Die Ereignisschleife wird bereits ausgeführt, sodass Sie exec()
nicht aufrufen müssen. Qt's Fenster integrieren sich in die native Event-Schleife, und an dieser Front ist alles gut.
Sie müssen einmal QCoreApplication::processEvents
aufrufen. Es wird die aktuelle Anwendungsinstanz in die Windows-Ereignisschleife integrieren, und das ist es.
So könnte Ihr Startup-Code wie folgt aussehen:
%Vor% Die startup()
und shutdown()
sollten zu geeigneten Zeiten (beim Prozess attach und detach) aufgerufen werden.
Alte Antwort folgt. Dies ist nicht mehr ganz auf dem neuesten Stand.
Ein kurzes Beispiel finden Sie unten, für ein vollständiges in sich abgeschlossenes Beispiel siehe meine andere Antwort .
Es ist nicht tragbar und deshalb rät die Qt-Dokumentation davon ab. Es funktioniert gut unter Windows. Der Hauptthread ist keine Magie - nicht unter Windows. Cocoa auf OS X ist in gewisser Weise ungeschickt und macht es scheinbar unmöglich: (.
Beachten Sie, dass, wenn die Anwendung, die die DLL lädt, bereits Qt verwendet, Sie nichts weiter tun müssen. Stellen Sie sicher, dass Sie Ihre DLL mit demselben C ++ - Compiler kompilieren, mit der gleichen C ++ - Laufzeit verknüpfen und eine Version von Qt verwenden, die mit der von der Anwendung verwendeten binär kompatibel ist. Sie benötigen dann keine eigene Instanz von QApplication
. Um eine nützliche Arbeit zu erledigen, zeigen Sie ein Widget oder instanziieren Sie QObjects
mit Timern, die sie beschäftigen. Sie können auch QMetaObject::invokeMethod(obj, "mySlot", Qt::QueuedConnection)
anstelle von Timern verwenden: Der Aufruf wird ausgeführt, wenn die Steuerung zur Ereignisschleife zurückkehrt.
Wenn das nicht möglich ist, dann ist das folgende die einzige Option. Funktioniert gut, soweit ich das beurteilen kann.
Beachten Sie, dass ich hier ein bisschen sarkastisch bin: Die Bedingungen im vorherigen Absatz werden möglicherweise zuverlässig erfüllt, wenn Sie der Autor der Anwendung sind, die die DLL verwendet. Sonst - vergiss es.
%Vor%