Pregunta

Estoy escribiendo un archivo DLL que se utiliza como un plugin por otra aplicación y le gustaría capacidades de apalancamiento de Qt.
Tengo todas las clases establecidas, compilar y ejecutar, pero no está emitiendo señales. Por lo tanto, parece que no hay QEventLoop.

Intento 1:
He modificado mi clase principal subclase QThread en lugar de QObject, y en el run () crear un QEventLoop, conectar todas las señales / ranuras, y exec con el hilo.
Pero fracasa diciendo que no se puede tener un QEventLoop sin QApplication.

Intento 2:
He modificado la clase principal (siendo la subclasificación de la QThraed) para crear una instancia de un lugar QCoreApplication, conectar todas las señales / ranuras, a continuación, la aplicación exec.
Advierte que la QApplication no fue creado en el hilo principal (), y las señales todavía no emitirá.

No estoy muy seguro de qué hacer aquí. Obviamente no puedo crear un QCoreApplication en la aplicación que se utilice mi complemento, y no puedo emitir señales sin uno.

he incluido un simple (y horriblemente escrito) aplicación de prueba que deben ilustrar mi problema:

Cualquier ayuda se agradece!

main.cpp:

#include <iostream>
#include "ThreadThing.h"
using namespace std;
int main(int argc, char *argv[])
{
    cout << "Main: " << 1 << endl;
    ThreadThing thing1;
    cout << "Main: " << 2 << endl;
    thing1.testStart();
    cout << "Main: " << 3 << endl;
    thing1.testEnd();
    cout << "Main: " << 4 << endl;
    thing1.wait(-1);
    cout << "Main: " << 5 << endl;
    return 0;
}

ThreadThing.h:

#ifndef THREADTHING_H
#define THREADTHING_H
#include <QThread>
class ThreadThing : public QThread
{
    Q_OBJECT
public:
    ThreadThing();
    virtual void run();
    void testStart();
    void testEnd();
public slots:
    void testSlot();
signals:
    void testSignal();
};
#endif//THREADTHING_H

ThreadThing.cpp:

#include "ThreadThing.h"
#include <iostream>
#include <QCoreApplication>

using namespace std;

ThreadThing::ThreadThing()
{
    cout << "Constructor: " << 1 << endl;
    this->start();
    cout << "Constructor: " << 2 << endl;
}

void ThreadThing::run()
{
    cout << "Run: " << 1 << endl;
    int i = 0;
    cout << "Run: " << 2 << endl;
    QCoreApplication* t = new QCoreApplication(i, 0);
    cout << "Run: " << 3 << endl;
    connect(this, SIGNAL(testSignal()), this, SLOT(testSlot()), Qt::QueuedConnection);
    cout << "Run: " << 4 << endl;
    t->exec();
    cout << "Run: " << 5 << endl;
}

void ThreadThing::testStart()
{
    cout << "TestStart: " << 1 << endl;
    emit testSignal();
    cout << "TestStart: " << 2 << endl;
}

void ThreadThing::testEnd()
{
    cout << "TestEnd: " << 1 << endl;
    this->quit();
    cout << "TestEnd: " << 1 << endl;
}

void ThreadThing::testSlot()
{
    cout << "TEST WORKED" << endl;
}

Salida:

Main: 1
Constructor: 1
Constructor: 2
Main: 2
TestStart: 1
TestStart: 2
Main: 3
TestEnd: 1
TestEnd: 1
Main: 4
Run: 1
Run: 2
WARNING: QApplication was not created in the main() thread.
Run: 3
Run: 4
¿Fue útil?

Solución

Tienes para crear una QCoreApplication o QApplication y Tienes para hacerlo en el hilo principal.

Eso no significa que no se puede poner el código para que, en su plugin ... a menos que la aplicación siempre se ejecuta cada plugin en su propio hilo.

Si la aplicación es de hacer eso, entonces puede intentar enganchar a cualquier bucle de eventos nativa los usos de aplicaciones, y se encargará de esta una llamada a alguna función en su plugin en el hilo principal.

Otros consejos

He tenido éxito creando un QCoreApplication y ejecutarlo en un subproceso de fondo. Este es no una implementación estándar, pero puede trabajar para la funcionalidad de señal / ranura simple. Hice esto para una aplicación de iOS nativo con un legado de gran Qt código base.

//I really don't do anything but run on a background thread
class MyQtAppForBackgroundThread : public QCoreApplication 
{
    Q_OBJECT
    ...
}

 //iOS specific code here...
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void){
        // This spawns a QCoreApplication on a background thread in an attempt to create something that can
        // queue signals across threads
        qtApp = new MyQtAppForBackgroundThread(smArgc, smArgv);
        qtApp->exec();

    });

Señales dispararon sobre el mismo hilo en el que estaban conectados, será atrapado. Para señales de agarre en diferentes hilos debe crear y sondear un QEventLoop en el hilo donde se crearon las señales.

//Fire me periodically on the thread the signals and slots were connected
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeUserInputEvents, 500 );
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top