Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Multiple calls to same slot
Forum Updated to NodeBB v4.3 + New Features

Multiple calls to same slot

Scheduled Pinned Locked Moved General and Desktop
17 Posts 4 Posters 6.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kushagra
    wrote on last edited by
    #1

    i have put this code in a for loop
    @
    EnginioReply *reply=client->downloadUrl(query);

     connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(urlDownload(EnginioReply*)));
    

    @
    this slot calls another slot which needs to executed
    now what is happening is that the next call to the slot(i.e. second call to the slot mentioned in code) is being made before the execution for previous one has been completed
    is it possible that i can prevent the second call to same slot to allow previous one to complete and then go forward with next one?

    1 Reply Last reply
    0
    • K Offline
      K Offline
      koahnig
      wrote on last edited by
      #2

      Do you call the next slot through another emitted signal?
      AFAIK in that case the slots are executed in sequence of signals. If there is already a signal waiting your new signal will be placed in he queue.

      However, a slot is nothing else that any an ordinary method of your class. The only specialty is that you can use it as slot in a connect statement. So you may call the slot method directly without the deroute through an additional signal.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kushagra
        wrote on last edited by
        #3

        yes the next slot is being called when another signal is emitted
        i also accept that a slot is another method of class so when second signal is emitted it calls the second slot which means that control does not comes back till execution of second slot is completed
        but it is not happening this way, after calling the second function before its execution is completed, control goes back to main and because of for loop on
        @
        EnginioReply *reply=client->downloadUrl(query);

             connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(urlDownload(EnginioReply*)));
        

        @

        the whole process repeats again

        1 Reply Last reply
        0
        • C Offline
          C Offline
          code_fodder
          wrote on last edited by
          #4

          If your objects are in the same thread they will be connected "Directly" by default. This means when it recieves the signal it will process it immediatley (and stop what it is doing, even if it is processing a previous signal)... this means it acts somewhat like an interrupt....

          Usually you want things to be processed in the same order that they arrive. You can force this by using Queued connection:

          @
          connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(urlDownload(EnginioReply*)), Qt::QueuedConnection);
          @

          From what I read of your issue, this could be the problem (if they are in the same thread). If they are in different threads then Qt::QueuedConnection is default anyway.

          1 Reply Last reply
          0
          • K Offline
            K Offline
            kushagra
            wrote on last edited by
            #5

            i am sorry i tried as you mentioned but it does not seems to be working
            let me post the code

            @
            for(int i=0;i<2;i++)
            {
            query.insert("id",fileId[i]);

              qDebug()<<"query 1: "<<query;
            
            EnginioReply *reply=client->downloadUrl(query);
            

            connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(showResult(EnginioReply*)),Qt::QueuedConnection);
            connect(client,SIGNAL(error(EnginioReply*)),this,SLOT(showError(EnginioReply*)));

            }

            void MainWindow::showResult(EnginioReply *reply)
            {
            QString url=reply->data().value("expiringUrl").toString();
            // qDebug()<<"Reply data: "<<reply->data();
            QNetworkRequest request(url);

            m_reply=client->networkManager()->get(request);
            m_reply->setParent(this);
            connect(m_reply,SIGNAL(finished()),this,SLOT(downloadFinished()),Qt::QueuedConnection);
            qDebug()<<"Exiting showResult";
            

            }

            void MainWindow::downloadFinished()
            {
            QByteArray imageData=m_reply->readAll();
            m_image.loadFromData(imageData);
            qDebug()<<m_image.isNull()<<" Check for NULL";
            pix[index]=QPixmap::fromImage(m_image.scaled(300,300,Qt::KeepAspectRatio,Qt::SmoothTransformation));

                qDebug()<<"Exiting downloadFinish";
                if(index==0)
                {
                    ui->label->setPixmap(pix[0]);
                    index=1;
                }
                if(index==1)
                {
                    ui->label_2->setPixmap(pix[1]);
            
                }
            

            }
            @

            1 Reply Last reply
            0
            • C Offline
              C Offline
              code_fodder
              wrote on last edited by
              #6

              Do you have more then one instance of the objects called "reply" and "client"?

              You are making the same connection to them more then once, I can't see the reason for this.

              Also with the queued connection, I would use it for all of your connections, this should at least sort out any order-related issues.

              Also.... where are your "emits"?, you have connected some signals but not actually emitted anything.... (or you have omitted that code?)

              1 Reply Last reply
              0
              • IamSumitI Offline
                IamSumitI Offline
                IamSumit
                wrote on last edited by
                #7

                Hii..
                I think Your second slots gets called due to for loop ,because loop gets executed in a very fast manner,so it forces to second call even the first not finished.
                //note that -->the finish() signal emitted when the reply has finished processing.

                Be Cute

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  code_fodder
                  wrote on last edited by
                  #8

                  That kind of error/conflict would be corrected by using Queued connection :)

                  But still... I see lots of "connects", but no signal emits...

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kushagra
                    wrote on last edited by
                    #9

                    ok so i noticed my error
                    and i have added emit instructions but i need more advice
                    now if u notice i have a reply pointer
                    @
                    EnginioReply *reply=client->downloadUrl(query);
                    @
                    i need to call the slot when it finishes but it takes time to finish
                    so how do i delay execution of other instructions to allow it to be finished

                    1 Reply Last reply
                    0
                    • C Offline
                      C Offline
                      code_fodder
                      wrote on last edited by
                      #10

                      Sorry, your question is not quite accurate enough to understand.

                      When you say "need to call the slot when it finishes" can you clarify what is:
                      "it" - what?
                      "the slot" - which slot?

                      Thanks! - also if you have fixed your code and added emit's, then please re-display your new code, probably easier to talk about it then :)

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        kushagra
                        wrote on last edited by
                        #11

                        my apologies
                        by it i meant slot
                        each reply is connects to a slot at different points and i want those slots to be called after reply has received all the data
                        in this case
                        @
                        EnginioReply *reply=client->downloadUrl(query);

                        connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(showResult(EnginioReply*)),Qt::QueuedConnect
                        @

                        1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          kushagra
                          wrote on last edited by
                          #12

                          and as you asked for the displaying the code where i have added emit signals
                          @
                          for(int i=0;i<2;i++)
                          {
                          query.insert("id",fileId[i]);

                            qDebug()<<"query 1: "<<query;
                          
                          EnginioReply *reply=client->downloadUrl(query);
                          if(reply->isFinished())
                          {   qDebug()<<"Check for reply->data()"<<reply->data().isEmpty();
                              emit reply->finished(reply);
                              connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(showResult(EnginioReply*)),Qt::QueuedConnection);
                              connect(client,SIGNAL(error(EnginioReply*)),this,SLOT(showError(EnginioReply*)));
                          }
                          

                          }

                          void MainWindow::showResult(EnginioReply *reply)
                          {
                          QString url=reply->data().value("expiringUrl").toString();
                          // qDebug()<<"Reply data: "<<reply->data();
                          QNetworkRequest request(url);

                          m_reply=client->networkManager()->get(request);
                          m_reply->setParent(this);
                          
                          if(m_reply->isFinished())
                          {
                              emit m_reply->finished();
                          
                              connect(m_reply,SIGNAL(finished()),this,SLOT(downloadFinished()),Qt::QueuedConnection);
                          }
                          qDebug()<<"Exiting showResult";
                          

                          }

                          @

                          1 Reply Last reply
                          0
                          • C Offline
                            C Offline
                            code_fodder
                            wrote on last edited by
                            #13

                            ok, I think you have some issues with the way you are trying to use slots / signals.

                            I would really recommend re-reading the Qt slots and signals chapter - its not very long and is good reading :)

                            Your code could work by luck, but probably won't work at all. This is the way slots/signals should be done:

                            Define a signal in an object

                            Define a slot in an object

                            Use connect() to connect an existing signal to an existing slot

                            Add code to emit a signal (this can only be done AFTER the connection is made).

                            In your code you are doing an emit before you have connected the signal to a slot!, this means the emit will be ignored (not handled/consumed by any objects at the time of emit).

                            Connection must be done first so:
                            @
                            // First connect the objects
                            connect(reply,SIGNAL(finished(EnginioReply*)),this,SLOT(showResult(EnginioReply*)),Qt::QueuedConnection);

                            // Now emit a signal over the connection we just made.
                            emit reply->finished(reply);
                            @

                            But even this looks a bit wrong. The signal should really come from within the object itsself, such that some code within object reply should send out the emit:
                            @
                            // This code is somewhere within "reply"
                            emit finished();
                            @

                            1 Reply Last reply
                            0
                            • K Offline
                              K Offline
                              kushagra
                              wrote on last edited by
                              #14

                              Ok
                              I actually noticed something
                              I am trying to download data from enginio(the cloud server)
                              now data is taking a lot of time, a few milliseconds but it is long enough so that the data is not stored in reply before control starts executing further instructions
                              so i am at present also looking for a solution to pause execution of further commands till data is entered into reply

                              1 Reply Last reply
                              0
                              • C Offline
                                C Offline
                                code_fodder
                                wrote on last edited by
                                #15

                                You want to wait until you get the data before you go around the loop again?

                                Well, there are generally two methods of waiting:

                                • polling - keep looking at the result until it is finished. A very crude way to do this is loop until some check == true with a 1ms sleep in there so that it does not tie up the processor.
                                • Event-driven / separate threads. you make each request in a different thread and start them off. Once they complete they send a message back (via slot/signal) and then you move on to the next item.

                                the second method is the preferred one, but the first method is easier to apply to your code. But really, when you get a chance, you should try to implement the slot/signals correctly - this will help with later design, its a bit messy at the moment and it is limiting your options :(

                                1 Reply Last reply
                                0
                                • K Offline
                                  K Offline
                                  kushagra
                                  wrote on last edited by
                                  #16

                                  i think you are right ill start by reading the signal/slot chapter
                                  then ill come back to you if i face any problem

                                  1 Reply Last reply
                                  0
                                  • C Offline
                                    C Offline
                                    code_fodder
                                    wrote on last edited by
                                    #17

                                    its a good plan! :)

                                    1 Reply Last reply
                                    0

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved