Wait for the SLOT to finish

I am using QNetworkAccessManager to create a POST form.

I connected the signals and slots as:

connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(readCookies(QNetworkReply*))); 

Now I am making a request by doing:

 manager->post(request,postData); 

Now readCookies (QNetworkReply *) will be launched as soon as the SIGNAL is issued. Now, using the cookies that I get in this slot, I have to do another POST ..

Since the signals and slots are asynchronous, I want to wait until I get cookies from my first POST, and then again want to make another post using cookies that I received in the first POST, for example

 //Setting new request, headers etc... manager->post(request2,postData2); 

I want it to always be executed later after the first execution (so that I get the correct cookie value).

How? I am new to all of these SIGNALS AND SLOTS, so please carry me.

+4
source share
3 answers

You can make a message in your readCookies () slot:

 void readCookies( QNetworkReply* reply ) { if ( ...error? ) { report error... return; } ... manager->post(request2,postData2); } 

I will be called when the cookies are read and you can continue your message. Connect this to the second slot and so on. Managing multiple, possibly parallel, asynchronous operations, such as this can be a mistake, though, if you are managing many of them in the same object. I would suggest using the Command Pattern - here, which I described why I find it extremely useful in this context. A sequence of requests and asynchronous operations is encapsulated in a single object (in abbreviated form, with some pseudo-code):

 class PostStuffOperation : public QObject { Q_OBJECT public: enum Error { NoError=0, Error=1, ... }; Error error() const; //operation successful or not? QString errorString() const; //human-readable error description ... setters for all the information the operation needs ... void start() { ...start your first request and connect it to cookiesRead } public Q_SLOTS: void cookiesRead( QNetworkReply * ) { if ( error ) { // set error and errorString... emit finished( this ); //couldn't read cookies, so the operation fails return; } ... do post } void postFinished( QNetworkReply* ) { if ( error ) { // set error and errorString... } emit finished( this ); //post finished - that means the whole operation finished } Q_SIGNALS: void finished( PostStuffOperation* ); }; 

To start the operation, do

 PostStuffOperation op* = new PostStuffOperation( this ); ... pass data like server, port etc. to the operation connect( op, SIGNAL(finished()), this, SLOT(postOperationFinished()) ); op->start(); void postOperationFinished( PostStuffOperation* op ) { if ( op->error != PostStuffOperation::NoError ) { //handle error, eg show message box } } 

It makes sense to have a common base class for such operations; see, for example, KDE KJob .

+4
source

You can connect a signal from this to the slot from your manager and emit a signal after reading cookies. Example:

 connect(this, SIGNAL(cookiesRead()), manager, SLOT(PostAgain()); 

So your readCookies function will be:

 { // Read cookies emit cookiesRead(); } 

Of course, you can send all the data you want to receive to the slot.

Hope that helps

+4
source

You can send a second signal connected to another slot (re-request slot) if you have finished evaluating your first cookie. You can do it right in the slot. You can also call slots like a regular member function.

0
source

Source: https://habr.com/ru/post/1333182/


All Articles