Logo Questions Linux Laravel Mysql Ubuntu Git Menu

Wait for a SLOT to finish

I use QNetworkAccessManager to do form POST.

I have connected signals and slots as:


Now, I make a request by doing:


Now readCookies(QNetworkReply *) will be run as soon as SIGNAL is emitted. Now, using the Cookies which I get in this slot, I have to make one more POST..

As signals & slots are asynchronous, I want to wait till I get the cookies from my first POST and then I again want to do another post using the cookies I got in first POST like

//Setting new request, headers etc...

I want the later to always be executed after first one has executed (so that I get proper cookies value).

What is the way to go? I am new to all these SIGNALS & SLOTS so please bear with me.

like image 475
Abhijeet Rastogi Avatar asked Feb 26 '23 13:02

Abhijeet Rastogi

2 Answers

You can do the post in your readCookies() slot:

void readCookies( QNetworkReply* reply ) {
    if ( ...error? ) {
        report error...


I will be called when the cookies is read, and you can then continue with your post. Connect that to a second slot, and so on. Managing multiple, possibly parallely running asynchronous operations like this can become errorprone though, if you manage many of them in a single object. I would suggest to use the Command Pattern - here I described why I find it extremely useful in exactly this context. The sequence of request and asnychronous operations is encapsulated in a single object (abbreviated, with some pseudo-code):

class PostStuffOperation : public QObject {
    enum Error {

    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
    ... do post

 void postFinished( QNetworkReply* ) {
     if ( error ) {
         // set error and errorString...

    emit finished( this ); //post finished - that means the whole operation finished
    void finished( PostStuffOperation* );

To start the operation, you do

PostStuffOperation op* = new PostStuffOperation( this );
... pass data like server, port etc. to the operation
connect( op, SIGNAL(finished()), this, SLOT(postOperationFinished()) );

void postOperationFinished( PostStuffOperation* op ) {
    if ( op->error != PostStuffOperation::NoError ) {
        //handle error, e.g. show message box

It makes sense to have a common baseclass for such operations, see e.g. KDE's KJob.

like image 146
Frank Osterfeld Avatar answered Mar 08 '23 01:03

Frank Osterfeld

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

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

So your readCookies function will be:

   // Read cookies
   emit cookiesRead();

Of course you can send all data you want form signal to slot.

Hope that helps

like image 20
Patrice Bernassola Avatar answered Mar 08 '23 01:03

Patrice Bernassola