Could one thread get the signal from the other one in the qt?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Could one thread get the signal from the other one in the qt?



I don't have the deep knowledge about QT thread.

I am gonna QT app that has the background thread.

The background thread is executed in the other thread different to the main one.

In the background thread, this makes new thread for calling the api by using signal-slot mechanism.

For example.


//BackThread.h

Q_OBJECT
public:
BackThread()
thread = new QThread; moveToThread(thread);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), this, SLOT(deleteLater()));


public slots:
void start() thread->start();
void terminate()thread->quit();
void on_readyResult(QNewtworkReply* reply) // process response
void dowork()
//This is called by signal 'signal_dowork()'
APIManager * manager = new APIManager;
connect(manager, SIGNAL(readyResult(QNetworkReply*)), this, SLOT(on_readyResult(QNeworkReply*)));
connect(this, SIGNAL(signal_callAPI(QString)), manager, SLOT(callAPI(QString)));
connect(manager, SIGNAL(readyResult(QNetworkReply*)), manager, SLOT(terminate())); //Here api call is needed only one time.
manager->start();
while(true)
QThread::sleep(20);
emit signal_callAPI("http://url.com");


signals:
signal_callAPI(QString);
private:
QThread *thread;


//APIManager.h

Q_OBJECT
public:
APIManager()
thread = new QThread; moveToThread(thread);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), this, SLOT(deleteLater()));


callAPI(QString api)
QNetworkAccessManager *manager;
manager = new QNetworkAccessManager();
// Send web request by this QNewtorkAccessManager ....
//...
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_readyReply(QNetworkReply*)));

public slots:
void start() thread->start();
void terminate()thread->quit();
void on_readyReply(QNewtworkReply* reply)
//This is called by the signal 'finished(QNetworkReply*)' of the QNetworkAccessManager, so the readyResult signal is emitted.
emit readyResult(reply); //this signal is emitted,but the connected slot 'on_readyResult' is not fired whenever.

signals:
readyResult(QString);
private:
QThread *thread;


//MainApp.cpp
BackThread * backthread = new BackThread;
connect(this, SIGNAL(signal_dowork()), backthread, SLOT(dowork()));
backthread->start();
emit signal_dowork(); //This calls dowork() slot.



As you could see, the main app starts the background thread and emits the signal for the background thread to do something. (signal_dowork())

This calls dowork() slot of the BackThread Object.

In this BackThread Object, this starts new Thread to call the api.

BackThread and APIManager thread are different.
APIManager class sends the web request and receives the reply using signal-slot.

When receiving the signal ,finished(QNetworkReply*) of the QNewtworkAccessManager, in the APIManager, the slot , on_readyReply(QNetworkReply*) , emits the signal again for the BackThread to process this reply.

But the BackThread doesn't receive this signal whenever.

In the QT document, it is described that


signal_dowork()


dowork()


APIManager class


finished(QNetworkReply*)


on_readyReply(QNetworkReply*)



Auto Connection (default) If the signal is emitted in the thread which
the receiving object has affinity then the behavior is the same as the
Direct Connection. Otherwise, the behavior is the same as the Queued
Connection.

Queued Connection The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.



Though the APIManager emits the signal readyResult(reply); and this signal is connected to the slot on_readyResult(QNetworkReply*), that slot is not called.

Is it caused becuase BackThread and APIManager are executed in the different threads?

And then how could the app connects the signal and slots of the different threads?

Please explain me why this happens.

Thanks


readyResult(reply);


on_readyResult(QNetworkReply*)





In connect(manager, SIGNAL(readyResult(QNetworkReply*)), manager, SLOT(terminate())); manager's terminate() slot is invoked?
– talent_depeloper
Aug 10 at 0:59


connect(manager, SIGNAL(readyResult(QNetworkReply*)), manager, SLOT(terminate()));





Yeah , so the manager memory is freed. I've debugged.
– Andrew Li
Aug 10 at 1:00


manager





connect(manager, SIGNAL(readyResult(QNetworkReply*)), this, SLOT(on_readyResult(QNeworkReply*)));connect(manager, SIGNAL(readyResult(QNetworkReply*)), manager, SLOT(terminate())); the manager received readyResult then trigger terminate & on_readyResult. so destroyed itself first then connection lost.
– Jiu
Aug 10 at 1:39



connect(manager, SIGNAL(readyResult(QNetworkReply*)), this, SLOT(on_readyResult(QNeworkReply*)));connect(manager, SIGNAL(readyResult(QNetworkReply*)), manager, SLOT(terminate()));


manager


readyResult


terminate


on_readyResult





@Jiu , the signal readyResult is one of the manager.
– Andrew Li
Aug 10 at 1:41


readyResult





Try remove connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), this, SLOT(deleteLater())); in APIManager see what happen.
– Jiu
Aug 10 at 1:43


connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), this, SLOT(deleteLater()));


APIManager




1 Answer
1



I've found the issue in your code.

If the QOjbect is moved to the thread, they have different Event Loop.
Your dowork() function have the infinite loop.

So this blocks the Event Loop of the backthread.

So it couldn't get any signal from the other thread.

You have not to use the infinite loop in the slot of the QOjbect it blocks the Event Loop.


dowork()


backthread


QOjbect


void dowork()
//This is called by signal 'signal_dowork()'
APIManager * manager = new APIManager;
connect(manager, SIGNAL(readyResult(QNetworkReply*)), this, SLOT(on_readyResult(QNeworkReply*)));
connect(this, SIGNAL(signal_callAPI(QString)), manager, SLOT(callAPI(QString)));
connect(manager, SIGNAL(readyResult(QNetworkReply*)), manager, SLOT(terminate())); //Here api call is needed only one time.
manager->start();
while(true) //This blocks the event loop. Event Loop couldn't get any signal from the other thread.
QThread::sleep(20);
emit signal_callAPI("http://url.com");




Without while command, that works smoothly.
Hope this will help you.


while





And then how could the app have the infinite loop?
– Andrew Li
Aug 12 at 1:08





It is your option, I think you could like this. connect(this,SIGNAL(restart()),this,SLOT(dowork()),Qt::QueuedConnection). If you use Qt::AutoConnection, it blocks the current function. So it calls the dowork() infinitely.
– talent_depeloper
Aug 12 at 1:17



connect(this,SIGNAL(restart()),this,SLOT(dowork()),Qt::QueuedConnection)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

make 2 or more post in bootsrap

Store custom data using WC_Cart add_to_cart() method in Woocommerce 3

Firebase Auth - with Email and Password - Check user already registered