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. QTimer::singleShot(x00, [=]{ mysignal1; }); .... multiple time

QTimer::singleShot(x00, [=]{ mysignal1; }); .... multiple time

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 4.9k Views
  • 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.
  • gfxxG Offline
    gfxxG Offline
    gfxx
    wrote on last edited by gfxx
    #1

    As a post title use these lambda function for call 2-3 void each pushbutton toggle = true .... in more accurate description I create a qthread subbclass and after the user it have press a pushbutton on gui (toggled pushbutton) I call a void with a "series" of lambda functions.. so these signal it use for call the void on my qthread:

    mainwindows::myfunc(bool it)
    {
          if(it){
           QTimer::singleShot(100, [=]{ mysignal1; });
           QTimer::singleShot(300, [=]{ mysignal2; });
           QTimer::singleShot(500, [=]{ mysignal3; });
           QTimer::singleShot(700, [=]{ mysignal4; });
    
    }
    
    /* I use the mainwindows signal for call mythread void  ex:*/
    connect(this, SIGNAL(mysignal1(int)), myqthread, SLOT(mySigvoid(int)), Qt::Queuedconnection);
    ........
    .......
    /*in mythread....*/
    
    myqthread::run.....
    {
    /* .... mutex and off switch .... */
    do(;;)
    {
     switch(myvalue)
          case 1:
                 myvoid1();
                 break;
          case 2:
                 myvoid2();
                 break;
    
    ...../*etc etc...*/
    }
    }
    
    myqthread::myvoid1(){/*some stupid code called from signal1 from mainwindows...*/}
    myqthread::myvoid2(){/*some stupid code called from signal2 from mainwindows...*/}
    myqthread::myvoid3(){/*some stupid code called from signal3 from mainwindows...*/}
    myqthread::myvoid4(){/*some stupid code called from signal4 from mainwindows...*/}
    
    myqthread::mySigvoid(int theNewValue){
     if(theNewValue == thOldOne){}
    else {myvalue = theNewValue;}
    }
    

    sometime these "sequence" is not call .... these is related to bad use of these type of lambda function or the error is only on my /some stupid code/??

    regards
    giorgio

    bkt

    J.HilkJ 1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by
      #2

      Hi, if you call your mythread void functions directly from your mainwindows signal; that means your're calling from one function to a function in another thread, and that's the reason I think why the call fails sometimes.

      1 Reply Last reply
      1
      • gfxxG gfxx

        As a post title use these lambda function for call 2-3 void each pushbutton toggle = true .... in more accurate description I create a qthread subbclass and after the user it have press a pushbutton on gui (toggled pushbutton) I call a void with a "series" of lambda functions.. so these signal it use for call the void on my qthread:

        mainwindows::myfunc(bool it)
        {
              if(it){
               QTimer::singleShot(100, [=]{ mysignal1; });
               QTimer::singleShot(300, [=]{ mysignal2; });
               QTimer::singleShot(500, [=]{ mysignal3; });
               QTimer::singleShot(700, [=]{ mysignal4; });
        
        }
        
        /* I use the mainwindows signal for call mythread void  ex:*/
        connect(this, SIGNAL(mysignal1(int)), myqthread, SLOT(mySigvoid(int)), Qt::Queuedconnection);
        ........
        .......
        /*in mythread....*/
        
        myqthread::run.....
        {
        /* .... mutex and off switch .... */
        do(;;)
        {
         switch(myvalue)
              case 1:
                     myvoid1();
                     break;
              case 2:
                     myvoid2();
                     break;
        
        ...../*etc etc...*/
        }
        }
        
        myqthread::myvoid1(){/*some stupid code called from signal1 from mainwindows...*/}
        myqthread::myvoid2(){/*some stupid code called from signal2 from mainwindows...*/}
        myqthread::myvoid3(){/*some stupid code called from signal3 from mainwindows...*/}
        myqthread::myvoid4(){/*some stupid code called from signal4 from mainwindows...*/}
        
        myqthread::mySigvoid(int theNewValue){
         if(theNewValue == thOldOne){}
        else {myvalue = theNewValue;}
        }
        

        sometime these "sequence" is not call .... these is related to bad use of these type of lambda function or the error is only on my /some stupid code/??

        regards
        giorgio

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        @gfxx Since Qt 5.2 a so called "context object" was added. When that object is destroyed, the connection is broken and the context is also used for the thread affinity.
        The lambda will be called in the thread of the event loop of the object used as context).

        From what I can see, you do not use such an context object in your lambda. That should make the thread where the Timer is created/started the thread that calls the function.
        That should be the reason why it sometimes works and sometimes it does not.


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        gfxxG 1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @gfxx Since Qt 5.2 a so called "context object" was added. When that object is destroyed, the connection is broken and the context is also used for the thread affinity.
          The lambda will be called in the thread of the event loop of the object used as context).

          From what I can see, you do not use such an context object in your lambda. That should make the thread where the Timer is created/started the thread that calls the function.
          That should be the reason why it sometimes works and sometimes it does not.

          gfxxG Offline
          gfxxG Offline
          gfxx
          wrote on last edited by gfxx
          #4

          @J.Hilk In these case I must renew my code ...

          @hskoglund ... not understand your suggest: is not possible using signal/slot mechanism for call some function from mainwindows to qthread?
          Obviously I'm not a genius otherwise I would not need the forum .... But I need you to explain the concept better if you can. Is for me learning ... and sorry for my horrible English. Thank you.

          for more precision myqthread have a run function .... run function see my mainwindow signal and after it call myvoidx ... inside run function loop I have a big case switch statement that see the integer value of my signal ... so my signal is only integer value of the same variable....

          A better example of my mechanism...

          mainwindows::myfunc(bool it)
          {
                if(it){
                 QTimer::singleShot(100, [=]{ mysignal1; });
                 QTimer::singleShot(300, [=]{ mysignal2; });
                 QTimer::singleShot(500, [=]{ mysignal3; });
                 QTimer::singleShot(700, [=]{ mysignal4; });
          
          }
          
          /* I use the mainwindows signal for call mythread void  ex:*/
          connect(this, SIGNAL(mysignal1(int,int,bool)), myqthread, SLOT(mySigvoid(int,int,bool)), Qt::Queuedconnection);/*(int,int,bool) registerNumber, slaveStationNumber, on or off*/
          ........
          .......
          /*in mythread....*/
          
          int registernumber = 0;
          
          myqthread::run.....
          {
          /* .... mutex and off switch .... */
          do(;;)
          {
          if(myvalueIschangedTrue){
           switch(myvalue)
                case 1:
                        if(value){
                       myregisterwriting(slavestationnr, 1/*registernumber*/, 1/*registerValue = 1*/);}
                       else{myregisterwriting(slavestationnr, 1/*registernumber*/r, 0/*registerValue = 0*/);}
                       break;
                case 2:
                       myregisterwriting(slavestationnr, 2/*registernumber*/, 1/*registerValue = 1*/);}
                       else{myregisterwriting(slavestationnr, 2/*registernumber*/r, 0/*registerValue = 0*/);}
                       break;
          
          ...../*etc etc...*/
          }
          }
          }
          
          myqthread::myvoid1(){/*some stupid code called from signal1 from mainwindows...*/}
          myqthread::myvoid2(){/*some stupid code called from signal2 from mainwindows...*/}
          myqthread::myvoid3(){/*some stupid code called from signal3 from mainwindows...*/}
          myqthread::myvoid4(){/*some stupid code called from signal4 from mainwindows...*/}
          
          myqthread::mySigvoid(int theNewValue){
           if(theNewValue == thOldOne){}
          else {myvalue = theNewValue;}
          }
          

          Thanks to all the answers.
          Giorgio

          bkt

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

            Hi,

            Why that infinite loop ? It looks like you should have a worker object that implements that big switch or maybe a map of int and function pointers.

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

            gfxxG 1 Reply Last reply
            0
            • SGaistS SGaist

              Hi,

              Why that infinite loop ? It looks like you should have a worker object that implements that big switch or maybe a map of int and function pointers.

              gfxxG Offline
              gfxxG Offline
              gfxx
              wrote on last edited by gfxx
              #6

              @SGaist said in QTimer::singleShot(x00, [=]{ mysignal1; }); .... multiple time:

              Hi,

              Why that infinite loop ? It looks like you should have a worker object that implements that big switch or maybe a map of int and function pointers.

              a map of int (and I have omitted in above example the mutex and stop command)..... I have linked for each command on gui an int value that I send to mythread .... I keep checking (with a delay of 20ms) if the myvalue (int) is changed and if it is changed I work switch case ... Recalling a modbus log writing function. .... for major precision on my code there is an if before the switch/case statement .... is true if myvalue is changed .... I renew my example in above thread ... It's just a representation of the mechanism .... it works very well but sometimes the commands are not executed .... I do not think it's a problem of writing time on the modbus, so I tried to ask where I could be wrong. Is my using the signal / slot mechanism from mainwindow to myqthread wrong? .... Check back the code above ... i fixed it to make you understand better what i'm doing .... sorry but i do not have the file on this tablet.

              any how in 5.8 on linux is necessary to install libmodbus or qt5.8 have a new modbus library instead (actually I use 5.6 and program to upgrade to new 5.8)?

              regards
              giorgio

              bkt

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

                What if you get two changes in a row ? One might get lost.

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

                gfxxG 1 Reply Last reply
                0
                • SGaistS SGaist

                  What if you get two changes in a row ? One might get lost.

                  gfxxG Offline
                  gfxxG Offline
                  gfxx
                  wrote on last edited by
                  #8

                  @SGaist said in QTimer::singleShot(x00, [=]{ mysignal1; }); .... multiple time:

                  What if you get two changes in a row ? One might get lost.

                  You are in right but is for these that I use lambda with singleshot timer .... if I must send more than one change in one command I sent one after 100ms and the second one after 600ms. In mythread myvalueIschangedTrue function must receive 1 only command at time ... If I have 2 identical command the second one is cancel, if I have 2 different command I must use lambda singleshot trick ..... But I could also make a speck of buffer for the signals .... to be able to store up to 10 signals sent in one line .... or more simply instead of the registers use the individual bits ... so I could send up to 16 signals in one line.
                  But the problem is not this. The problem is: is it correct to use my trick (lambda + singleshot) to send more signals at a time or is it better to follow other roads? Yes what is it?

                  HSKOGLUND WROTE: Hi, if you call your mythread void functions directly from your mainwindows signal; that means your're calling from one function to a function in another thread, and that's the reason I think why the call fails sometimes.

                  So my sistem is not correct? not Understand very well .... The thing is that I still have to learn a lot of things. Anyone can tell me if what I'm doing is correct or not?

                  I think I understand the "context object" affairs ... it make sense .... so I must limit the use of single shot timer + lambda .... But this does not say if my thing is correct or not.

                  Thnks to all.
                  Giorgio

                  bkt

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

                    Can you provide a description of what your application should be doing exactly ?

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

                    gfxxG 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      Can you provide a description of what your application should be doing exactly ?

                      gfxxG Offline
                      gfxxG Offline
                      gfxx
                      wrote on last edited by gfxx
                      #10

                      @SGaist for shure ...

                      I have a gui with 20 pushbutton or more .... everytime the users press a button I send one ore more modbus holding register writing .....
                      the modbus master rtu is located into mythread and I have a do(;;) cicle for intercept the new value send from gui .... the switch case statement intercept the new value and call the right void with the right register number and value ...this void execute the modbus writing. .... later I attach the right signal slot sequence and the real code.

                      the code:

                      /***** in mainwindows ****/
                      /*********************************** k::cm_xxxxxxxx_4 is a global int number  present in file  global _konst.h    *******/
                      
                      connect(ui->s12_2, SIGNAL(toggled(bool)), this, SLOT(sss12_2(bool)));  /*s12_2 is a pushbutton*/
                      
                      mThread4 = new Kmecth4(this);
                      connect(this, SIGNAL(sendInOut(int,bool,int)), mThread4, SLOT(receiveNum4(int,bool,int)), Qt::DirectConnection);
                      mThread4->start();
                      
                      
                      
                      
                          if(MultiMachine != 0)
                          {
                              switch (MultiMachine) {
                              case 1:
                                  if(cntrPC1)
                                  {
                                      modbus_set_slave(ctx, 1);
                                      ret = modbus_write_register(ctx, ModBusMultiRegNr, valueMultiReg);
                                      this->msleep(10);
                                      qDebug() << "stato inviato ctx 01 = " <<  " reg = " << ModBusMultiRegNr << " valore = " << valueMultiReg;
                                  }
                                  control4 = false;
                                  modbus_flush(ctx);
                                  break;
                              case 2:
                                  if(cntrPC2)
                                  {
                                      modbus_set_slave(ctx, 2);
                                      ret = modbus_write_register(ctx, ModBusMultiRegNr, valueMultiReg);
                                      this->msleep(10);
                                      qDebug() << "stato inviato ctx 02 = " <<  " reg = " << ModBusMultiRegNr << " valore = " << valueMultiReg;
                                  }
                                  control4 = false;
                                  modbus_flush(ctx);
                                  break;
                      /* etc etc etc......*/
                      

                      regards
                      Giorgio

                      bkt

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

                        Are you trying to model your modbus system with that code ? Because it looks like a state machine might be more fitting.

                        On a site note, your use of QMutex in the run method is wrong, you're not protecting anything since it's a local mutex.

                        By the way, Qt provides now support for modbus in the QtSerialBus module.

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

                        gfxxG 1 Reply Last reply
                        1
                        • SGaistS SGaist

                          Are you trying to model your modbus system with that code ? Because it looks like a state machine might be more fitting.

                          On a site note, your use of QMutex in the run method is wrong, you're not protecting anything since it's a local mutex.

                          By the way, Qt provides now support for modbus in the QtSerialBus module.

                          gfxxG Offline
                          gfxxG Offline
                          gfxx
                          wrote on last edited by gfxx
                          #12

                          @SGaist mmmm maybe ... but I have in these case a lot of parallel state .... and the execution phisically is not on that pc ... so execution signal is returned with delay ... The add more difficult to use state machine .... In any case state machine framework seems to me something complicated to handle having many gui signals and many feedback from the outside world ... indeed the framework state machine seems to me something complicated when it could be all inserted in the struct with control/buffer function and ini files for shutdown event (at least From the examples I saw). I still have to find the example code that convinces me to use StateMachine.

                          Anyway, writing on the forum I'm convinced that the heart of the problem is the delays, so I'll have to put my code so that there is not a single write function for all the commands.

                          About QMutex ... you are in right.

                          About new support of mudbus int QtSerialbus into QT5.8 ... I'm trying it out these days .... It sounds like a good thing and I think I'll use it instead of libmodbus.

                          regards
                          Giorgio

                          bkt

                          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