PDA

View Full Version : Qt signals/slots dll for non-Qt app



bareil76
20th October 2014, 17:14
Hi All,

I have a problem with the signal/slots for my dll.


Here is my setup:

1) MySystemWrapper.dll is a c wrapper that can be called from python (or other app.. but for now I use python to debug).
The connect() function calls the Qt dll that cannot be called with other apps.


bool connect(){
QAppPriv::pApp = new QCoreApplication(QAppPriv::argc, QAppPriv::argv); //to handle signals and slots
mSystem = new mySystem();

return true;
}

2) In the mySystem.dll the constructor looks like this:


MySystem::MySystem()
{

QThread *thread = new QThread;

//USB HID interface
plugNPlay = new HID_PnP();
plugNPlay->moveToThread(thread);
plugNPlay->start();



////signal slots test

processEventsTmr = new QTimer(this);
processEventsTmr->setInterval(1000); //x ms between each process events
connect(processEventsTmr,SIGNAL(timeout()), this, SLOT(processMyEvents()));

}



The problem I have is that processMyEvents() is never called. So the signal/slot does not work in the MySystem object.

HOWEVER, the signal/slot ARE WORKING in the plugNPlay object.

I think my problem is with the way new QCoreApplication is called but I can figure it out.

I have read this (http://stackoverflow.com/questions/2150488/using-a-qt-based-dll-in-a-non-qt-application) over and over again!

Thanks

d_stranz
20th October 2014, 19:05
So where are you calling QCoreApplication::exec() on your application instance? If the event loop isn't running, events don't get processed. You also can't have more than one QCoreApplication instance, but your connect() method will create a new one every time it is called.

I think you need to read the stackoverflow post at least one more time, and follow the suggestions exactly.

bareil76
21st October 2014, 15:55
Ok..

here is what I have now.

What works:
a) The plugNPlay object has timers and connects that work.
b) connect(plugNPlay, SIGNAL(JustConnected(bool)),this,SLOT(initialize(b ool)), Qt::QueuedConnection); is also working
c) connect(retryTmr,SIGNAL(timeout()), this, SLOT(handleNoResponse())); also works.

What doesn't work:
a) In the initialize(bool) slot.. I have retryTmr->start();... the system complains that:

QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread



1) First MySystemWrapper which is called first. I had to put the MySystem object in another thread because if I don't.. nothing works!


bool MYSYSTEMWRAPPERSHARED_EXPORT connect(){

mMySystem = new MySystem();
mMySystem->moveToThread(thread2);
thread2->start();
QMetaObject::invokeMethod(mMySystem, "run", Qt::QueuedConnection);


return true;
}

2) Then, the MySystem class is called from the above. The constructor is only to start the QApp. With the signal that will call exec().... ONLY then I call the run() that will created my program objects.


MySystem::MySystem(QObject *parent) :
QObject(parent)
{
if (QAppPriv::pThread == NULL)
{
qDebug()<< "QAppPriv::pThread created";
// Separate thread for application thread
QAppPriv::pThread = new QThread();
// Direct connection is mandatory
QObject::connect(QAppPriv::pThread, SIGNAL(started()), this, SLOT(OnExec()), Qt::DirectConnection);
QAppPriv::pThread->start();
}


}
void MySystem::OnExec(){
if (QCoreApplication::instance() == NULL)
{
qDebug()<< "QAppPriv::pApp created";
QAppPriv::pApp = new QCoreApplication(QAppPriv::argc, QAppPriv::argv);
QAppPriv::pApp->exec();
if (QAppPriv::pApp)
delete QAppPriv::pApp;
}
}



void MySystem::run(){
QThread *thread = new QThread;
plugNPlay = new HID_PnP();
plugNPlay->moveToThread(thread);

isConnected = false;



retryTmr = new QTimer(this);
retryTmr->setSingleShot(true);
retryTmr->setInterval(10); //10ms between retry
connect(retryTmr,SIGNAL(timeout()), this, SLOT(handleNoResponse()));



connect(plugNPlay, SIGNAL(JustConnected(bool)),this,SLOT(initialize(b ool)),
Qt::QueuedConnection);
}

bareil76
24th October 2014, 13:19
The above worked... I had another problem. SOLVED