Domanda

Sto scrivendo una DLL che viene utilizzato come un plugin da un'altra applicazione e vorrebbe sfruttare le capacità di Qt.
Ho tutte le classi di set up, compilazione e l'esecuzione, ma non sono presenti segnali emessa. Così sembra come se non c'è QEventLoop.

Tentativo 1:
Ho modificato la mia classe principale per creare una sottoclasse QThread invece di QObject, e nel run () creare un QEventLoop, collegare tutti i segnali / slot, ed exec il filo.
Ma non riesce dicendo che non si può avere un QEventLoop senza QApplication.

Tentativo 2:
Ho modificato la classe principale (ancora sottoclasse la QThraed) per istanziare invece un QCoreApplication, collegare tutti i segnali / slot, quindi exec l'applicazione.
Avverte che QApplication non è stato creato nel thread principale (), e ancora non emette segnali.

Non sono davvero sicuro di cosa fare qui. Io, ovviamente, non può creare una QCoreApplication nell'applicazione che utilizzerà il plug-in, e non posso emettere segnali senza uno.

Ho incluso un semplice (e orribilmente scritto) applicazione di test che dovrebbe illustrare il mio problema:

Qualsiasi aiuto sarebbe apprezzato!

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

Output:

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
È stato utile?

Soluzione

sono per creare un QCoreApplication o QApplication e sono per farlo nel thread principale.

Ciò non significa che non si può mettere il codice per che nel vostro plugin ... a meno che l'applicazione viene eseguita sempre ogni plugin nel proprio thread.

Se l'applicazione è di farlo, allora si può provare l'aggancio a qualsiasi ciclo di eventi nativo applicazione utilizza, e organizzare per chiamare una qualche funzione nel vostro plugin nel thread principale.

Altri suggerimenti

Ho avuto successo la creazione di un QCoreApplication e in esecuzione su un thread in background. Questo è non un'implementazione standard, ma può funzionare per funzionalità segnale / slot di semplice. Ho fatto questo per un iOS app nativa con una grande eredità base di codice Qt.

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

    });

I segnali sparati sullo stesso thread in cui sono stati collegati saranno catturati. Per catturare segnali su diversi thread è necessario creare e interrogare un QEventLoop sul thread in cui sono stati creati i segnali.

//Fire me periodically on the thread the signals and slots were connected
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeUserInputEvents, 500 );
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top