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. A problem with single slot connected to multiple signals
Forum Updated to NodeBB v4.3 + New Features

A problem with single slot connected to multiple signals

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 5 Posters 4.2k Views 3 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.
  • O Offline
    O Offline
    Oleg_Suf
    wrote on last edited by kshegunov
    #1

    Hello! Can't figure out what the problem is in my project with single slot connected to several signals.
    Seems like the execution sequence of code lines is broken.

    My GUI app has, let's say, three signals, which are connected to one slot. The signals are emitted
    very fast, and slot fulfillment takes a bit of time. As you can see in example below, triggerings
    of the slot begin in one sequence, and finish in completely different sequence. And I can't understand
    how to fix it.
    The sources of signals are single-shot timers, the troubling slot is "on_TimerTick()":

    --dialog.h--

    {
    private slots:
    	void on_TimerTick();
    	void on_pushButton_clicked();//launching timers
    
    private:
    	Ui::Dialog ui;
    	void Print(QString message);
    	QTimer* tmr1;
    	QTimer* tmr2;
    	QTimer* tmr3;
    	void mySleep(int msec);
    };
    
    //---dialog.cpp---
    //constructor
    {
    	tmr1 = new QTimer(this);
    	tmr2 = new QTimer(this);
    	tmr3 = new QTimer(this);
    
    	tmr1->setObjectName("tmr1");
    	tmr2->setObjectName("tmr2");
    	tmr3->setObjectName("tmr3");
    
    	tmr1->setSingleShot(true);
    	tmr2->setSingleShot(true);
    	tmr3->setSingleShot(true);
    
    	connect(tmr1, &QTimer::timeout, this, &Dialog::on_TimerTick);
    	connect(tmr2, &QTimer::timeout, this, &Dialog::on_TimerTick);
    	connect(tmr3, &QTimer::timeout, this, &Dialog::on_TimerTick);
    }
    
    void Dialog::Print(QString message)
    {
    	ui->textBrowser->append(message);
    }
    void Dialog::mySleep(int msec)//imitation of delay in slot's execution
    {
    	QEventLoop loop;
    	QTimer::singleShot(msec, &loop, SLOT(quit()));
    	loop.exec();
    }
    //The weird Slot
    void Dialog::on_TimerTick()
    {
    	Print(QString("Started ") + QObject::sender()->objectName());
    	mySleep(2);
    	Print(QString("Stopped ") + QObject::sender()->objectName());
    }
    void Dialog::on_pushButton_clicked()
    {
    	tmr1->start(1);
    	tmr2->start(1);
    	tmr3->start(1);
    }
    

    Output:

    Started tmr3
    Started tmr1
    Started tmr2
    Stopped tmr2
    Stopped tmr1
    Stopped tmr3
    

    I've tried to use overloaded versions of connect-method in constructor with fifth parameter:
    Qt::QueuedConnection, but it didn't help. And if slot would be executed in different threads I'd probably
    just put the QMutex to enforce the right sequence of slot executions, like:
    //--What I want-example-

    Started tmr3
    Started tmr1
    Started tmr2
    Stopped tmr3
    Stopped tmr1
    Stopped tmr2
    

    //----------------------,
    but all slot triggerings are performed in single (main) thread.

    Can anybody please explain how to fix the situation? Thanks

    [Russian version: https://forum.qt.io/topic/81859/проблема-при-соединении-нескольких-сигналов-с-одним-слотом ~kshegunov]

    kshegunovK 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Oleg_Suf
      Hi
      If you remove mySleep(2); does it still come out of order ?

      O 1 Reply Last reply
      0
      • mrjjM mrjj

        @Oleg_Suf
        Hi
        If you remove mySleep(2); does it still come out of order ?

        O Offline
        O Offline
        Oleg_Suf
        wrote on last edited by
        #3

        @mrjj said in A problem with single slot connected to multiple signals:

        @Oleg_Suf
        Hi
        If you remove mySleep(2); does it still come out of order ?

        If I remove mySleep(2) the order becomes correct. But in real task some PCs do have a certain latency, so I wish I could get rid of it in my work project, but...

        mrjjM 1 Reply Last reply
        0
        • O Oleg_Suf

          @mrjj said in A problem with single slot connected to multiple signals:

          @Oleg_Suf
          Hi
          If you remove mySleep(2); does it still come out of order ?

          If I remove mySleep(2) the order becomes correct. But in real task some PCs do have a certain latency, so I wish I could get rid of it in my work project, but...

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Oleg_Suf

          Ok i was wondering the the local event loop would interfere with
          the regular and it seems it does.

          If they perform heavy task in real world, you should rather
          use threads as not to hang the main thread.

          1 Reply Last reply
          0
          • Vinod KuntojiV Offline
            Vinod KuntojiV Offline
            Vinod Kuntoji
            wrote on last edited by
            #5

            @Oleg_Suf ,

            Set some delay between the timers.
            void Dialog::on_pushButton_clicked()
            {
            tmr1->start(1);
            tmr2->start(2);
            tmr3->start(3);
            }

            C++, Qt, Qt Quick Developer,
            PthinkS, Bangalore

            O 1 Reply Last reply
            0
            • Vinod KuntojiV Vinod Kuntoji

              @Oleg_Suf ,

              Set some delay between the timers.
              void Dialog::on_pushButton_clicked()
              {
              tmr1->start(1);
              tmr2->start(2);
              tmr3->start(3);
              }

              O Offline
              O Offline
              Oleg_Suf
              wrote on last edited by
              #6

              @Vinod-Kuntoji said in A problem with single slot connected to multiple signals:

              @Oleg_Suf ,

              Set some delay between the timers.

              I would love to do this, but it's just a model example, real app signals come from hardware, and I'm unable to affect its reaction time.
              I guess I have two choises then - 1) Try to reduce the slot execution time by all means; 2) Perform every new task in separate thread and use mutex (I'd really wish to avoid that))

              1 Reply Last reply
              0
              • mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by mrjj
                #7

                @Oleg_Suf
                You could wait some ticks before stopping

                ala something like
                (for testing)

                void Dialog::on_TimerTick()
                {
                static int tickcc=1;
                if (tickcc == 1)
                Print(QString("Started ") + QObject::sender()->objectName());
                else if (tickcc > 4 ) {
                Print(QString("Stopped ") + QObject::sender()->objectName());
                tickcc =0;
                }
                tickcc++;
                }

                1 Reply Last reply
                0
                • O Oleg_Suf

                  Hello! Can't figure out what the problem is in my project with single slot connected to several signals.
                  Seems like the execution sequence of code lines is broken.

                  My GUI app has, let's say, three signals, which are connected to one slot. The signals are emitted
                  very fast, and slot fulfillment takes a bit of time. As you can see in example below, triggerings
                  of the slot begin in one sequence, and finish in completely different sequence. And I can't understand
                  how to fix it.
                  The sources of signals are single-shot timers, the troubling slot is "on_TimerTick()":

                  --dialog.h--

                  {
                  private slots:
                  	void on_TimerTick();
                  	void on_pushButton_clicked();//launching timers
                  
                  private:
                  	Ui::Dialog ui;
                  	void Print(QString message);
                  	QTimer* tmr1;
                  	QTimer* tmr2;
                  	QTimer* tmr3;
                  	void mySleep(int msec);
                  };
                  
                  //---dialog.cpp---
                  //constructor
                  {
                  	tmr1 = new QTimer(this);
                  	tmr2 = new QTimer(this);
                  	tmr3 = new QTimer(this);
                  
                  	tmr1->setObjectName("tmr1");
                  	tmr2->setObjectName("tmr2");
                  	tmr3->setObjectName("tmr3");
                  
                  	tmr1->setSingleShot(true);
                  	tmr2->setSingleShot(true);
                  	tmr3->setSingleShot(true);
                  
                  	connect(tmr1, &QTimer::timeout, this, &Dialog::on_TimerTick);
                  	connect(tmr2, &QTimer::timeout, this, &Dialog::on_TimerTick);
                  	connect(tmr3, &QTimer::timeout, this, &Dialog::on_TimerTick);
                  }
                  
                  void Dialog::Print(QString message)
                  {
                  	ui->textBrowser->append(message);
                  }
                  void Dialog::mySleep(int msec)//imitation of delay in slot's execution
                  {
                  	QEventLoop loop;
                  	QTimer::singleShot(msec, &loop, SLOT(quit()));
                  	loop.exec();
                  }
                  //The weird Slot
                  void Dialog::on_TimerTick()
                  {
                  	Print(QString("Started ") + QObject::sender()->objectName());
                  	mySleep(2);
                  	Print(QString("Stopped ") + QObject::sender()->objectName());
                  }
                  void Dialog::on_pushButton_clicked()
                  {
                  	tmr1->start(1);
                  	tmr2->start(1);
                  	tmr3->start(1);
                  }
                  

                  Output:

                  Started tmr3
                  Started tmr1
                  Started tmr2
                  Stopped tmr2
                  Stopped tmr1
                  Stopped tmr3
                  

                  I've tried to use overloaded versions of connect-method in constructor with fifth parameter:
                  Qt::QueuedConnection, but it didn't help. And if slot would be executed in different threads I'd probably
                  just put the QMutex to enforce the right sequence of slot executions, like:
                  //--What I want-example-

                  Started tmr3
                  Started tmr1
                  Started tmr2
                  Stopped tmr3
                  Stopped tmr1
                  Stopped tmr2
                  

                  //----------------------,
                  but all slot triggerings are performed in single (main) thread.

                  Can anybody please explain how to fix the situation? Thanks

                  [Russian version: https://forum.qt.io/topic/81859/проблема-при-соединении-нескольких-сигналов-с-одним-слотом ~kshegunov]

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #8

                  @Oleg_Suf said in A problem with single slot connected to multiple signals:

                  And I can't understand
                  how to fix it.

                  You can't reliably change that. A timer will fire the first opportunity it has (i.e. when control returns to the event loop) but there's no guarantee for ordering it depends on which timers have timed out at the time of check, and which haven't. In any case you should not depend on the order of appearance of signal emissions/slot calls.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Hi,

                    Can you explain how your application is supposed to react to these hardware "signals" ? And also why is it the same slot that is called for what seems to be different hardware ?

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    O 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      Hi,

                      Can you explain how your application is supposed to react to these hardware "signals" ? And also why is it the same slot that is called for what seems to be different hardware ?

                      O Offline
                      O Offline
                      Oleg_Suf
                      wrote on last edited by
                      #10

                      @SGaist said:

                      Can you explain how your application is supposed to react to these hardware "signals" ?

                      Hardware sends data, my program processes these packages of data in the same way every time, and every time responds;

                      And also why is it the same slot that is called for what seems to be different hardware ?

                      No, hardware is the same, it just triggers very fast

                      kshegunovK 1 Reply Last reply
                      0
                      • O Oleg_Suf

                        @SGaist said:

                        Can you explain how your application is supposed to react to these hardware "signals" ?

                        Hardware sends data, my program processes these packages of data in the same way every time, and every time responds;

                        And also why is it the same slot that is called for what seems to be different hardware ?

                        No, hardware is the same, it just triggers very fast

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        I don't follow, why would you need to ensure a specific order of the slot execution/signal emission then?

                        Read and abide by the Qt Code of Conduct

                        O 1 Reply Last reply
                        0
                        • kshegunovK kshegunov

                          I don't follow, why would you need to ensure a specific order of the slot execution/signal emission then?

                          O Offline
                          O Offline
                          Oleg_Suf
                          wrote on last edited by Oleg_Suf
                          #12

                          @kshegunov said:

                          I don't follow, why would you need to ensure a specific order of the slot execution/signal emission then?

                          Because order matters to user. Anyway, I concluded, that if I can't increase time interval between signals emittions, I have to decrease slot execution time, there is no other way to ensure consistency in this case. The given example is simplified, but in original task, I ended up performing data processing (which was shown as "mySleep(2);") in worker thread, and all GUI things (which were shown as Print() methods) - in main thread.
                          Thanks to everyone

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            What order is that ?

                            Are you also ensuring that the hardware sends its data always at the same pace and in the same order ?

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            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