Question

J'écris une DLL qui est utilisé comme un plug-in par une autre application et que vous souhaitez tirer parti des capacités de Qt.
J'ai toutes les classes mis en place, compilation et l'exécution, mais pas les signaux sont émis. Il semble donc que si il n'y a pas QEventLoop.

Tentative 1:
J'ai modifié ma classe principale sous-classe QThread au lieu de QObject, et dans la course () crée un QEventLoop, connecter tous les signaux / slots et exec le fil.
Mais il ne parvient en disant que vous ne pouvez pas avoir un QEventLoop sans QApplication.

Tentative 2:
J'ai modifié la classe principale (toujours le sous-classement QThraed) à la place instancier un QCoreApplication, connecter tous les signaux / slots, puis lancer l'application.
Met en garde contre que le QApplication n'a pas été créé dans le thread principal (), et encore n'émettre des signaux.

Je ne suis pas vraiment sûr de ce qu'il faut faire ici. Je ne peux évidemment pas créer un QCoreApplication dans l'application qui utilisera mon plug-in, et je ne peux pas émettre des signaux sans.

J'ai inclus une application de test simple (et horriblement écrit) qui devrait illustrer mon problème:

Toute aide serait appréciée!

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;
}

Sortie:

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
Était-ce utile?

La solution

Vous pour créer un QCoreApplication ou QApplication et vous Vous pour le faire dans le thread principal.

Cela ne signifie pas que vous ne pouvez pas mettre le code pour que votre plugin ... à moins que l'application fonctionne toujours chaque plugin dans son propre fil.

Si l'application est le faire, vous pouvez alors essayer d'accrochage pour tout boucle événement natif de l'application utilise et organiser pour appeler une fonction dans votre plug-in dans le thread principal.

Autres conseils

J'ai eu du succès et la création d'un QCoreApplication en cours d'exécution sur un fil d'arrière-plan. Ceci est pas une implémentation standard, mais peut fonctionner pour simple signal / fonctionnalité de fente. Je l'ai fait pour une application iOS native avec un grand héritage Qt codebase.

//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();

    });

Les signaux tirés sur le même fil où ils ont été connectés seront pris. Pour attraper des signaux sur différents threads vous devez créer et interroger un QEventLoop sur le fil où les signaux ont été créés.

//Fire me periodically on the thread the signals and slots were connected
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeUserInputEvents, 500 );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top