Una forma en que funciona en Windows es comenzar QApplication
en una separada QThread
. No es portátil, no funciona en OS X (estoy investigando una solución).
Pero, no necesita un hilo por separado. Si inyectas tu código en una aplicación en ejecución, ya tiene un bucle de evento. Solo necesita crear un objeto global QApplication
y listo. El ciclo de eventos ya se está ejecutando, por lo que no es necesario que llame al exec()
. Las ventanas de Qt se integran con el bucle de eventos nativo, y todo es bueno en ese frente.
Usted do need para llamar al QCoreApplication::processEvents
una vez. Integrará la instancia de la aplicación actual en el bucle de eventos de Windows, y eso es todo.
lo tanto, su código de inicio podría ser como sigue:
int * argc = nullptr;
char ** argv = nullptr;
QApplication * app = nullptr;
MainWindow * win = nullptr;
static void startup() {
argc = new int(1);
argv = new char*[1];
argv[0] = strdup("dummy");
auto app = new QApplication(*argc, argv);
auto w = new MainWindow;
w->show();
app->processEvents();
}
static void shutdown()
{
delete win;
delete app;
free argv[0];
delete [] argv;
delete argc;
}
El startup()
y shutdown()
deberían ser llamados en los momentos apropiados (en proceso de unir y separar).
Respuesta antigua a continuación. Esto ya no está completamente actualizado.
Un breve ejemplo está debajo, para un ejemplo autónomo completo vea mi other answer.
No es portátil y por eso la documentación de Qt desaconseja su uso. Funciona bien en Windows. El hilo principal no es mágico, no en Windows. Cocoa en OS X es torpe en cierto modo y lo hace imposible, aparentemente :(.
Tenga en cuenta que si la aplicación que carga el archivo DLL ya usa Qt, entonces no hay nada más que hacer. Asegúrese de compilar el archivo DLL con el mismo compilador de C++, el enlace contra el mismo tiempo de ejecución de C++, y utiliza una versión de Qt que es binaria compatible con la utilizada por la aplicación. Entonces no necesita su propia instancia de QApplication
. Para hacer un trabajo útil, muestre un widget o una instancia de alguna QObjects
con temporizadores que conseguirá ocupados también puede utilizar QMetaObject::invokeMethod(obj, "mySlot", Qt::QueuedConnection)
en lugar de utilizar los temporizadores:.. se realizará la llamada cuando el control vuelve al bucle de eventos
Si eso no es posible, entonces el siguiente es su única opción. Wo Está bien, por lo que puedo decir.
Tenga en cuenta que soy un poco sarcástico aquí: Las condiciones en el párrafo anterior se cumplirán de forma confiable tal vez si usted es el autor de la aplicación que utiliza el DLL. De lo contrario, olvídate de eso.
class AppThread : public QThread {
int & argc;
char ** argv;
int result;
void run() {
QApplication a(argc, argv);
Dialog d;
d.show();
result = a.exec();
}
public:
AppThread(int & argc_, char ** argv_) : argc(argc_), argv(argv_) {}
}
int __stdcall DLLStart(void) {
AppThread * thread = new AppThread(argc, argv);
thread->start();
return 0;
}
void __stdcall DLLStop(void) {
qApp->thread()->quit();
qApp->thread()->wait();
}
No lo sé. Solo puedo sugerir que te guste en window_qt.cpp en el código de opencv.org. Utiliza Qt para mostrar una sola ventana con su propio bucle de eventos como parte de una biblioteca que no es de Qt. –
¿Se llama a 'DllStart' desde' DllMain'? ¿O llamado desde el proceso de llamada? – Synxis
@MB, cualquier pista en la que se encuentre el representante (http://code.opencv.org/projects/opencv/repository). La búsqueda no lo encuentra, tendrá un botín. –