Frage

Ich schreibe eine DLL, die als Plugin von einer anderen Anwendung verwendet wird und möchten Hebel Qt Fähigkeiten.
Ich habe alle Klassen einrichten, Kompilieren und Ausführen, aber keine Signale ausgesendet werden. So scheint es, als gäbe es keine QEventLoop ist.

Der Versuch 1:
Ich änderte meine Hauptklasse QThread statt QObject, und in der run () erstellen QEventLoop, schließen Sie alle Signale / Slots und exec den Faden zu Unterklasse.
Aber es funktioniert nicht sagen, dass Sie nicht eine QEventLoop ohne QApplication haben können.

Der Versuch 2:
Ich änderte die Hauptklasse (immer noch die QThraed Subklassen), stattdessen eine QCoreApplication zu instanziiert, schließen alle Signale / Slots, dann die Anwendung exec.
Warnt davor, dass die QApplication wurde nicht in der main () Thread erstellt, und wird immer noch nicht senden Signale aus.

Ich bin nicht wirklich sicher, was hier zu tun. Ich kann natürlich nicht QCoreApplication in der Anwendung erstellen, die meine Plugin verwenden, und ich kann nicht senden Signale aus, ohne ein.

Ich habe eine einfache (und schrecklich geschrieben) Testanwendung enthalten, die mein Problem veranschaulichen sollte:

Jede mögliche Hilfe würde geschätzt!

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

Ausgabe:

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
War es hilfreich?

Lösung

Sie Haben eine QCoreApplication oder QApplication zu erstellen und Sie Haben es im Hauptthread zu tun.

Das bedeutet nicht, dass Sie nicht den Code für den in Ihrem Plugin setzen können ... es sei denn, die Anwendung immer jedes Plugin in einem eigenen Thread ausgeführt wird.

Wenn die Anwendung ist , das zu tun, dann können Sie versuchen, in Einhaken zu, was nativen Ereignisschleife der App verwendet, und lassen Sie es eine Funktion in Ihrem Plugin im Hauptthread nennen.

Andere Tipps

Ich habe Erfolg hat eine QCoreApplication zu schaffen und es auf einem Hintergrund-Thread ausgeführt wird. Dies ist nicht eine Standard-Implementierung, sondern kann für einfache Signal / Slot-Funktionalität arbeiten. Ich tat dies für ein native iOS-App mit einer großen Vermächtnis Qt Code-Basis.

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

    });

gefeuert Signale auf dem gleichen Thread, in dem sie verbunden sind, werden gefangen werden. Um fangen Signale auf verschiedenen Threads müssen Sie erstellen und eine QEventLoop auf dem Thread abfragen, wo die Signale erstellt wurden.

//Fire me periodically on the thread the signals and slots were connected
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeUserInputEvents, 500 );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top