views:

655

answers:

1

I'm writing a DLL that is used as a plugin by another application and would like to leverage Qt's abilities.
I have all of the classes set up, compiling and running, but no signals are being emitted. So it seems as though there's no QEventLoop.

Attempt 1:
I modified my main class to subclass QThread instead of QObject, and in the run() create a QEventLoop, connect all signals/slots, and exec the thread.
But it fails saying that you can't have a QEventLoop without a QApplication.

Attempt 2:
I modified the main class (still subclassing the QThraed) to instead instantiate a QCoreApplication, connect all signals/slots, then exec the application.
Warns that the QApplication was not created in the main() thread, and still won't emit signals.

I'm not really sure what to do here. I obviously cannot create a QCoreApplication in the application that will use my plugin, and I cannot emit signals without one.

I have included a simple (and horribly written) test application which should illustrate my problem:

Any help would be appreciated!

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
+2  A: 

You have to create a QCoreApplication or QApplication and you have to do it in the main thread.

That doesn't mean you can't put the code for that in your plugin... unless the application always runs each plugin in its own thread.

If the application is doing that, then you can try hooking in to whatever native event loop the app uses, and arrange for it to call some function in your plugin in the main thread.

Intransigent Parsnip
Unfortunately, I can't touch anything in the main application that's using my plugin, and I only get to execute code when it calls a limited number of functions (DLL hooks and a couple of registered functions). On top of that, I don't know if my DLL gets called by the main thread or a plugin-managing one.The worst part is that even if I am in the main thread space, I cannot call the blocking exec() statement when it passes me control because I have to return for the main app to function.So is there absolutely no way that I can have a Qt lib for a non-Qt 3rd party app?
Marc
If you can't find a safe way to instantiate a QCoreApplication or QApplication then you can't use most of Qt. I would be surprised if you can't find some solution, though - after all, you have a C++ plugin, that can execute arbitrary code in the application process. There will be a way to make it work.
Intransigent Parsnip