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. Help with timer and JavaScript slot.
Forum Updated to NodeBB v4.3 + New Features

Help with timer and JavaScript slot.

Scheduled Pinned Locked Moved Solved General and Desktop
43 Posts 4 Posters 6.4k Views 2 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.
  • SPlattenS SPlatten

    @kshegunov , here is there requested source to the function:

    /**
     * @brief clsMainWnd::ptmrGetTimer
     * @param crstrID : Constant reference to ID to look-up timer
     * @return A pointer to the timer or nullptr if not found
     */
    QTimer* clsMainWnd::ptmrGetTimer(const QString& crstrID) {
        mpTimers::iterator itTimer(mmpTimers.find(crstrID));
        QTimer* pTimer(nullptr);
        if ( itTimer != mmpTimers.end() ) {
            pTimer = itTimer->second;
        }
        return pTimer;
    }
    

    I put breakpoint on first line of this, it does what I expected, nullptr is returned because on the first call the timer hasn't been registered.

    SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #22

    @SPlatten , I've reduced the source to just:

                QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                QThread* pobjCurrThread(QThread::currentThread());
        //Create new timer
    qdbg() << "Before Timer creation: " << pobjCurrThread;
                ptmrScript = new QTimer(pobjCurrThread);
        //Create connection to timer and script
    qdbg() << "Before QObject::connect: " << QThread::currentThread();
    
    

    And the output is still:

    Before Timer creation: QThread(0x600000264a00)
    S000000000029E000000000768T08:50:01.847W:QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QThread(0x600000264a00), parent's thread is QThread(0x6000000042c0), current thread is QThread(0x600000264a00)
    S000000000030E000000000768T08:50:01.847DL00000661F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
    Before QObject::connect: QThread(0x600000264a00)
    

    Kind Regards,
    Sy

    kshegunovK 1 Reply Last reply
    0
    • kshegunovK kshegunov

      @SPlatten said in Help with timer and JavaScript slot.:

      I have a breakpoint in the lambda function, first line, it doesn't get triggered.

      I don't expect it to get trigerred, but again, this is not what I wrote. Here's a reminder:

      Put a breakpoint in clsMainWnd::ptmrGetTimer and confirm it gets triggered (the breakpoint).

      Additionally provide its source, and finally add this to the very beginning of the mentioned function:
      [snip]

      SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by SPlatten
      #23

      @kshegunov , another attempt:

                  QThread* pobjCurrThread(QThread::currentThread());
          //Create new timer
      qdbg() << "Before Timer creation: " << pobjCurrThread;
                  ptmrScript = new QTimer;
                  ptmrScript->moveToThread(pobjCurrThread);
          //Create connection to timer and script
      qdbg() << "Before QObject::connect: " << QThread::currentThread();
      

      Output:

      Before Timer creation: QThread(0x600000264d00)
      S000000000029E000000000717T08:52:29.017DL00000662F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
      Before QObject::connect: QThread(0x600000264d00)
      

      Not seeing any errors in the debug, but execution isn't stopping in lambda either.

      Kind Regards,
      Sy

      1 Reply Last reply
      0
      • SPlattenS SPlatten

        @SPlatten , I've reduced the source to just:

                    QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                    QThread* pobjCurrThread(QThread::currentThread());
            //Create new timer
        qdbg() << "Before Timer creation: " << pobjCurrThread;
                    ptmrScript = new QTimer(pobjCurrThread);
            //Create connection to timer and script
        qdbg() << "Before QObject::connect: " << QThread::currentThread();
        
        

        And the output is still:

        Before Timer creation: QThread(0x600000264a00)
        S000000000029E000000000768T08:50:01.847W:QObject: Cannot create children for a parent that is in a different thread.
        (Parent is QThread(0x600000264a00), parent's thread is QThread(0x6000000042c0), current thread is QThread(0x600000264a00)
        S000000000030E000000000768T08:50:01.847DL00000661F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
        Before QObject::connect: QThread(0x600000264a00)
        
        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #24

        Hold your horses! You have managed to confuse me about what's modified and what goes in which function. In any case in the last piece of code; after this:

        //Create new timer
        qdbg() << "Before Timer creation: " << pobjCurrThread;
                    ptmrScript = new QTimer(pobjCurrThread);
            //Register the new timer using the supplied ID
        

        adding

        Q_ASSERT(clsJSON::pobjGetScriptEng()->currentThread() == QThread::currentThread());
        

        should get tripped.

        PS.
        This does nothing:

        ptmrScript = new QTimer;
        ptmrScript->moveToThread(pobjCurrThread);
        

        Read and abide by the Qt Code of Conduct

        SPlattenS 1 Reply Last reply
        1
        • kshegunovK kshegunov

          Hold your horses! You have managed to confuse me about what's modified and what goes in which function. In any case in the last piece of code; after this:

          //Create new timer
          qdbg() << "Before Timer creation: " << pobjCurrThread;
                      ptmrScript = new QTimer(pobjCurrThread);
              //Register the new timer using the supplied ID
          

          adding

          Q_ASSERT(clsJSON::pobjGetScriptEng()->currentThread() == QThread::currentThread());
          

          should get tripped.

          PS.
          This does nothing:

          ptmrScript = new QTimer;
          ptmrScript->moveToThread(pobjCurrThread);
          
          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #25

          @kshegunov said in Help with timer and JavaScript slot.:

          Q_ASSERT(clsJSON::pobjGetScriptEng()->currentThread() == QThread::currentThread());

          I cannot call currentThread() from pobjGetScriptEng(), it returns a pointer to QJSEngine.

          Kind Regards,
          Sy

          kshegunovK 1 Reply Last reply
          0
          • SPlattenS SPlatten

            @kshegunov said in Help with timer and JavaScript slot.:

            Q_ASSERT(clsJSON::pobjGetScriptEng()->currentThread() == QThread::currentThread());

            I cannot call currentThread() from pobjGetScriptEng(), it returns a pointer to QJSEngine.

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

            @SPlatten said in Help with timer and JavaScript slot.:

            I cannot call currentThread() from pobjGetScriptEng(), it returns a pointer to QJSEngine.

            Correct. I meant to write:

            Q_ASSERT(clsJSON::pobjGetScriptEng()->thread() == QThread::currentThread());
            

            Read and abide by the Qt Code of Conduct

            SPlattenS 2 Replies Last reply
            0
            • kshegunovK kshegunov

              @SPlatten said in Help with timer and JavaScript slot.:

              I cannot call currentThread() from pobjGetScriptEng(), it returns a pointer to QJSEngine.

              Correct. I meant to write:

              Q_ASSERT(clsJSON::pobjGetScriptEng()->thread() == QThread::currentThread());
              
              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #27

              @kshegunov , realised that after posting, modified output to:

              qdbg() << "Script Eng Thread: " << pobjScriptEng->thread();
              qdbg() << "Before Timer creation: " << pobjCurrThread;
              

              Result is:

              S000000000028E000000000784T09:03:45.243DL00000642F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
              Script Eng Thread: QThread(0x60000000c0d0)
              S000000000029E000000000784T09:03:45.243DL00000643F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
              Before Timer creation: QThread(0x60000026f260)
              S000000000030E000000000784T09:03:45.243W:QObject: Cannot create children for a parent that is in a different thread.
              (Parent is clsScriptHelper(0x600000208d80), parent's thread is QThread(0x60000000c0d0), current thread is QThread(0x60000026f260)
              S000000000031E000000000784T09:03:45.244DL00000664F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
              Before QObject::connect: QThread(0x60000026f260)
              

              Kind Regards,
              Sy

              kshegunovK 1 Reply Last reply
              0
              • kshegunovK kshegunov

                @SPlatten said in Help with timer and JavaScript slot.:

                I cannot call currentThread() from pobjGetScriptEng(), it returns a pointer to QJSEngine.

                Correct. I meant to write:

                Q_ASSERT(clsJSON::pobjGetScriptEng()->thread() == QThread::currentThread());
                
                SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by
                #28

                @kshegunov , have now changed code to:

                ptmrScript = new QTimer(this);
                ptmrScript->moveToThread(pobjScriptEngThread);
                ptmrScript->setInterval(cuintInterval);
                

                Output is now different:

                setupForm() !!!!
                S000000000028E000000000716T09:06:20.132W:QObject: Cannot create children for a parent that is in a different thread.
                (Parent is clsScriptHelper(0x600000202820), parent's thread is QThread(0x600000004150), current thread is QThread(0x60000025e1c0)
                S000000000029E000000000716T09:06:20.132W:QObject::startTimer: Timers cannot be started from another thread
                S000000000030E000000000716T09:06:20.132DL00000688F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
                Is timer active: true
                S000000000031E000000000716T09:06:20.132DL00000207Fsimon2.js[void clsScriptHelper::log]
                setupForm() !!!!
                

                I will add another API function to allow the script to start the timer.

                Kind Regards,
                Sy

                JonBJ 1 Reply Last reply
                0
                • SPlattenS SPlatten

                  @kshegunov , have now changed code to:

                  ptmrScript = new QTimer(this);
                  ptmrScript->moveToThread(pobjScriptEngThread);
                  ptmrScript->setInterval(cuintInterval);
                  

                  Output is now different:

                  setupForm() !!!!
                  S000000000028E000000000716T09:06:20.132W:QObject: Cannot create children for a parent that is in a different thread.
                  (Parent is clsScriptHelper(0x600000202820), parent's thread is QThread(0x600000004150), current thread is QThread(0x60000025e1c0)
                  S000000000029E000000000716T09:06:20.132W:QObject::startTimer: Timers cannot be started from another thread
                  S000000000030E000000000716T09:06:20.132DL00000688F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
                  Is timer active: true
                  S000000000031E000000000716T09:06:20.132DL00000207Fsimon2.js[void clsScriptHelper::log]
                  setupForm() !!!!
                  

                  I will add another API function to allow the script to start the timer.

                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by JonB
                  #29

                  @SPlatten said in Help with timer and JavaScript slot.:

                  Cannot create children for a parent that is in a different thread.

                  You still have this. Excuse my complete guesswork, but do you need to go new QTimer(); rather than new QTimer(this); to move to another thread? (I have never been sure which statement causes the error message, which you can discover by stepping over or putting in qDebug() markers.)

                  But if all this is beyond me and being solved by @kshegunov please ignore me --- I'm just watching the discussion :)

                  1 Reply Last reply
                  0
                  • SPlattenS SPlatten

                    @kshegunov , realised that after posting, modified output to:

                    qdbg() << "Script Eng Thread: " << pobjScriptEng->thread();
                    qdbg() << "Before Timer creation: " << pobjCurrThread;
                    

                    Result is:

                    S000000000028E000000000784T09:03:45.243DL00000642F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
                    Script Eng Thread: QThread(0x60000000c0d0)
                    S000000000029E000000000784T09:03:45.243DL00000643F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
                    Before Timer creation: QThread(0x60000026f260)
                    S000000000030E000000000784T09:03:45.243W:QObject: Cannot create children for a parent that is in a different thread.
                    (Parent is clsScriptHelper(0x600000208d80), parent's thread is QThread(0x60000000c0d0), current thread is QThread(0x60000026f260)
                    S000000000031E000000000784T09:03:45.244DL00000664F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
                    Before QObject::connect: QThread(0x60000026f260)
                    
                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #30

                    Right, so now comes the million bucks question(s):

                    Why is clsScriptHelper::createTimer called from thread different from the one pobjScriptEng has affinity for?
                    Why do you need to use threads to begin with?

                    As for the "solution":

                    QMetaObject::Connection cn = QObject::connect(ptmrScript
                                                                             ,&QTimer::timeout
                    

                    Shall provide a context object for the execution. Looking at the body, I'd say it should be something like:

                    QMetaObject::Connection cn = QObject::connect(ptmrScript , &QTimer::timeout, pobjScriptEng
                                                                             ,[pobjScriptEng
                                                                              ,ptmrScript
                                                                              ,strFile
                                                                              ,strFunc
                                                                              ,strScriptWithCall]() {
                    

                    Also the timer should be created with the correct affinity, I assume:

                    ptmrScript = new QTimer(pobjScriptEng);
                    

                    The original questions stand notwithstanding

                    PS: You have race conditions all over the place ...

                    Read and abide by the Qt Code of Conduct

                    SPlattenS 2 Replies Last reply
                    0
                    • kshegunovK kshegunov

                      Right, so now comes the million bucks question(s):

                      Why is clsScriptHelper::createTimer called from thread different from the one pobjScriptEng has affinity for?
                      Why do you need to use threads to begin with?

                      As for the "solution":

                      QMetaObject::Connection cn = QObject::connect(ptmrScript
                                                                               ,&QTimer::timeout
                      

                      Shall provide a context object for the execution. Looking at the body, I'd say it should be something like:

                      QMetaObject::Connection cn = QObject::connect(ptmrScript , &QTimer::timeout, pobjScriptEng
                                                                               ,[pobjScriptEng
                                                                                ,ptmrScript
                                                                                ,strFile
                                                                                ,strFunc
                                                                                ,strScriptWithCall]() {
                      

                      Also the timer should be created with the correct affinity, I assume:

                      ptmrScript = new QTimer(pobjScriptEng);
                      

                      The original questions stand notwithstanding

                      PS: You have race conditions all over the place ...

                      SPlattenS Offline
                      SPlattenS Offline
                      SPlatten
                      wrote on last edited by
                      #31

                      @kshegunov , createTimer is called by JavaScript:

                      function setupForm() {
                      	//Query all people	  
                      	xmleng.log(0, "setupForm() !!!!", cstrThis, 202);
                      	//Create request counter property
                      	xmleng.setProperty(cstrFormTest, cstrStageCtr, "0");
                      	//Create timer to issue SQL requests
                      	xmleng.createTimer("t1", 50, "simon2.js@testTimer");
                      	xmleng.log(0, "setupForm() !!!!", cstrThis, 207);
                      	xmleng.startTimer("t1");
                      };
                      
                      

                      Kind Regards,
                      Sy

                      1 Reply Last reply
                      0
                      • kshegunovK kshegunov

                        Right, so now comes the million bucks question(s):

                        Why is clsScriptHelper::createTimer called from thread different from the one pobjScriptEng has affinity for?
                        Why do you need to use threads to begin with?

                        As for the "solution":

                        QMetaObject::Connection cn = QObject::connect(ptmrScript
                                                                                 ,&QTimer::timeout
                        

                        Shall provide a context object for the execution. Looking at the body, I'd say it should be something like:

                        QMetaObject::Connection cn = QObject::connect(ptmrScript , &QTimer::timeout, pobjScriptEng
                                                                                 ,[pobjScriptEng
                                                                                  ,ptmrScript
                                                                                  ,strFile
                                                                                  ,strFunc
                                                                                  ,strScriptWithCall]() {
                        

                        Also the timer should be created with the correct affinity, I assume:

                        ptmrScript = new QTimer(pobjScriptEng);
                        

                        The original questions stand notwithstanding

                        PS: You have race conditions all over the place ...

                        SPlattenS Offline
                        SPlattenS Offline
                        SPlatten
                        wrote on last edited by
                        #32

                        @kshegunov , I've modified my source to:

                         QMetaObject::Connection cn = QObject::connect(ptmrScript
                                                                      ,&QTimer::timeout
                                                                      ,pobjScriptEng
                                                                      ,[pobjScriptEng
                                                                       ,ptmrScript
                                                                       ,strFile
                                                                       ,strFunc
                                                                       ,strScriptWithCall]() {
                        

                        still getting:

                        S000000000027E000000000747T09:17:30.915DL00000202Fsimon2.js[void clsScriptHelper::log]
                        setupForm() !!!!
                        S000000000028E000000000747T09:17:30.915DL00000207Fsimon2.js[void clsScriptHelper::log]
                        setupForm() !!!!
                        S000000000029E000000000747T09:17:30.915W:QObject::startTimer: Timers cannot be started from another thread
                        

                        Kind Regards,
                        Sy

                        kshegunovK 1 Reply Last reply
                        0
                        • SPlattenS SPlatten

                          @kshegunov , I've modified my source to:

                           QMetaObject::Connection cn = QObject::connect(ptmrScript
                                                                        ,&QTimer::timeout
                                                                        ,pobjScriptEng
                                                                        ,[pobjScriptEng
                                                                         ,ptmrScript
                                                                         ,strFile
                                                                         ,strFunc
                                                                         ,strScriptWithCall]() {
                          

                          still getting:

                          S000000000027E000000000747T09:17:30.915DL00000202Fsimon2.js[void clsScriptHelper::log]
                          setupForm() !!!!
                          S000000000028E000000000747T09:17:30.915DL00000207Fsimon2.js[void clsScriptHelper::log]
                          setupForm() !!!!
                          S000000000029E000000000747T09:17:30.915W:QObject::startTimer: Timers cannot be started from another thread
                          
                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #33

                          @SPlatten said in Help with timer and JavaScript slot.:

                          still getting

                          Did you also parent the timer to the QJSEngine?

                          Read and abide by the Qt Code of Conduct

                          SPlattenS 1 Reply Last reply
                          0
                          • kshegunovK kshegunov

                            @SPlatten said in Help with timer and JavaScript slot.:

                            still getting

                            Did you also parent the timer to the QJSEngine?

                            SPlattenS Offline
                            SPlattenS Offline
                            SPlatten
                            wrote on last edited by SPlatten
                            #34

                            @kshegunov, this is how it is now:

                            QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                            QThread* pobjScriptEngThread(pobjScriptEng->thread());
                            //Create new timer
                            ptmrScript = new QTimer();
                            ptmrScript->moveToThread(pobjScriptEngThread);
                            ptmrScript->setInterval(cuintInterval);
                            

                            Have just modified to:

                            QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                            QThread* pobjScriptEngThread(pobjScriptEng->thread());
                            //Create new timer
                            ptmrScript = new QTimer();
                            ptmrScript->setParent(pobjScriptEng);
                            ptmrScript->moveToThread(pobjScriptEngThread);
                            ptmrScript->setInterval(cuintInterval);
                            

                            Output is still:

                            S000000000027E000000000743T09:24:17.520DL00000202Fsimon2.js[void clsScriptHelper::log]
                            setupForm() !!!!
                            S000000000028E000000000743T09:24:17.520W:QObject::setParent: Cannot set parent, new parent is in a different thread
                            S000000000029E000000000743T09:24:17.520DL00000207Fsimon2.js[void clsScriptHelper::log]
                            setupForm() !!!!
                            

                            Kind Regards,
                            Sy

                            JonBJ kshegunovK KroMignonK 3 Replies Last reply
                            0
                            • SPlattenS SPlatten

                              @kshegunov, this is how it is now:

                              QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                              QThread* pobjScriptEngThread(pobjScriptEng->thread());
                              //Create new timer
                              ptmrScript = new QTimer();
                              ptmrScript->moveToThread(pobjScriptEngThread);
                              ptmrScript->setInterval(cuintInterval);
                              

                              Have just modified to:

                              QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                              QThread* pobjScriptEngThread(pobjScriptEng->thread());
                              //Create new timer
                              ptmrScript = new QTimer();
                              ptmrScript->setParent(pobjScriptEng);
                              ptmrScript->moveToThread(pobjScriptEngThread);
                              ptmrScript->setInterval(cuintInterval);
                              

                              Output is still:

                              S000000000027E000000000743T09:24:17.520DL00000202Fsimon2.js[void clsScriptHelper::log]
                              setupForm() !!!!
                              S000000000028E000000000743T09:24:17.520W:QObject::setParent: Cannot set parent, new parent is in a different thread
                              S000000000029E000000000743T09:24:17.520DL00000207Fsimon2.js[void clsScriptHelper::log]
                              setupForm() !!!!
                              
                              JonBJ Online
                              JonBJ Online
                              JonB
                              wrote on last edited by
                              #35

                              @SPlatten
                              Perhaps not relevant, but how can you go

                                          ptmrScript->moveToThread(pobjScriptEngThread);
                                          ptmrScript->setInterval(cuintInterval);
                              

                              Once moved to other thread, are you still allowed to set its interval from this (different) thread?

                              1 Reply Last reply
                              0
                              • SPlattenS SPlatten

                                @kshegunov, this is how it is now:

                                QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                                QThread* pobjScriptEngThread(pobjScriptEng->thread());
                                //Create new timer
                                ptmrScript = new QTimer();
                                ptmrScript->moveToThread(pobjScriptEngThread);
                                ptmrScript->setInterval(cuintInterval);
                                

                                Have just modified to:

                                QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                                QThread* pobjScriptEngThread(pobjScriptEng->thread());
                                //Create new timer
                                ptmrScript = new QTimer();
                                ptmrScript->setParent(pobjScriptEng);
                                ptmrScript->moveToThread(pobjScriptEngThread);
                                ptmrScript->setInterval(cuintInterval);
                                

                                Output is still:

                                S000000000027E000000000743T09:24:17.520DL00000202Fsimon2.js[void clsScriptHelper::log]
                                setupForm() !!!!
                                S000000000028E000000000743T09:24:17.520W:QObject::setParent: Cannot set parent, new parent is in a different thread
                                S000000000029E000000000743T09:24:17.520DL00000207Fsimon2.js[void clsScriptHelper::log]
                                setupForm() !!!!
                                
                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #36

                                Okay, I'm getting really tangled. Where is QTimer::start called? In createTimer? If so, then:

                                QTimer timer = new QTimer();
                                ...
                                // Connect the lambda with a context object, as mentioned!
                                ...
                                timer->start();
                                

                                Read and abide by the Qt Code of Conduct

                                SPlattenS 1 Reply Last reply
                                0
                                • kshegunovK kshegunov

                                  Okay, I'm getting really tangled. Where is QTimer::start called? In createTimer? If so, then:

                                  QTimer timer = new QTimer();
                                  ...
                                  // Connect the lambda with a context object, as mentioned!
                                  ...
                                  timer->start();
                                  
                                  SPlattenS Offline
                                  SPlattenS Offline
                                  SPlatten
                                  wrote on last edited by
                                  #37

                                  @kshegunov , I'm trying lots of things without taking the time to think about it.

                                  Kind Regards,
                                  Sy

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • SPlattenS SPlatten

                                    @kshegunov , I'm trying lots of things without taking the time to think about it.

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

                                    @SPlatten said in Help with timer and JavaScript slot.:

                                    I'm trying lots of things without taking the time to think about it.

                                    Yes, do so. Which is the whole reason I requested the call stack. How am I supposed to guess what calls what ...

                                    Read and abide by the Qt Code of Conduct

                                    SPlattenS 1 Reply Last reply
                                    0
                                    • kshegunovK kshegunov

                                      @SPlatten said in Help with timer and JavaScript slot.:

                                      I'm trying lots of things without taking the time to think about it.

                                      Yes, do so. Which is the whole reason I requested the call stack. How am I supposed to guess what calls what ...

                                      SPlattenS Offline
                                      SPlattenS Offline
                                      SPlatten
                                      wrote on last edited by
                                      #39

                                      @kshegunov I would provide the call stack, but execution doesn't halt, so where would you like me to break to then get the stack?

                                      Kind Regards,
                                      Sy

                                      kshegunovK 1 Reply Last reply
                                      0
                                      • SPlattenS SPlatten

                                        @kshegunov, this is how it is now:

                                        QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                                        QThread* pobjScriptEngThread(pobjScriptEng->thread());
                                        //Create new timer
                                        ptmrScript = new QTimer();
                                        ptmrScript->moveToThread(pobjScriptEngThread);
                                        ptmrScript->setInterval(cuintInterval);
                                        

                                        Have just modified to:

                                        QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                                        QThread* pobjScriptEngThread(pobjScriptEng->thread());
                                        //Create new timer
                                        ptmrScript = new QTimer();
                                        ptmrScript->setParent(pobjScriptEng);
                                        ptmrScript->moveToThread(pobjScriptEngThread);
                                        ptmrScript->setInterval(cuintInterval);
                                        

                                        Output is still:

                                        S000000000027E000000000743T09:24:17.520DL00000202Fsimon2.js[void clsScriptHelper::log]
                                        setupForm() !!!!
                                        S000000000028E000000000743T09:24:17.520W:QObject::setParent: Cannot set parent, new parent is in a different thread
                                        S000000000029E000000000743T09:24:17.520DL00000207Fsimon2.js[void clsScriptHelper::log]
                                        setupForm() !!!!
                                        
                                        KroMignonK Offline
                                        KroMignonK Offline
                                        KroMignon
                                        wrote on last edited by KroMignon
                                        #40

                                        @SPlatten I am always surprised how complicated you are trying to solve common issues.

                                        What is the real issue here?
                                        You want to create a timer in a specific thread and start it. I am right?
                                        QTimer muss be started, and stopped from the owned thread.
                                        That's not so complicated to solve:

                                        auto myTimer = new  QTimer();
                                        connect(myTimer; &QTimer::timeout, ...);
                                        // move to thread
                                        myTimer->moveToThread(theWorkingThread);
                                        
                                        // start the timer
                                        QTimer::singleShot(0, myTimer, [myTimer]() { myTimer->start(); } );
                                        

                                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                        SPlattenS 1 Reply Last reply
                                        1
                                        • KroMignonK KroMignon

                                          @SPlatten I am always surprised how complicated you are trying to solve common issues.

                                          What is the real issue here?
                                          You want to create a timer in a specific thread and start it. I am right?
                                          QTimer muss be started, and stopped from the owned thread.
                                          That's not so complicated to solve:

                                          auto myTimer = new  QTimer();
                                          connect(myTimer; &QTimer::timeout, ...);
                                          // move to thread
                                          myTimer->moveToThread(theWorkingThread);
                                          
                                          // start the timer
                                          QTimer::singleShot(0, myTimer, [myTimer]() { myTimer->start(); } );
                                          
                                          SPlattenS Offline
                                          SPlattenS Offline
                                          SPlatten
                                          wrote on last edited by SPlatten
                                          #41

                                          @KroMignon , thank you, will try this now, right now before trying your suggestion the output is:

                                          S000000000027E000000000715T09:32:03.904DL00000202Fsimon2.js[void clsScriptHelper::log]
                                          setupForm() !!!!
                                          S000000000028E000000000715T09:32:03.904DL00000207Fsimon2.js[void clsScriptHelper::log]
                                          setupForm() !!!!
                                          S000000000029E000000003405T09:32:06.594W:QObject::startTimer: Timers cannot be started from another thread
                                          

                                          @KroMignon, thank you so much, this now works, here are the prototypes:

                                          Q_INVOKABLE void createTimer(const QString& crstrID, const uint cuintInterval
                                                                      ,const QString& crstrFunction);
                                          Q_INVOKABLE void startTimer(const QString& crstrID);
                                          

                                          And the final implementations:

                                          /**
                                           * @brief clsScriptHelper::createTimer
                                           * @param crstrID : Constant reference to Timer ID
                                           * @param cuintInterval : Constant millisecond interval
                                           * @param crstrFunction : Constant reference to JSfile@Function
                                           */
                                          void clsScriptHelper::createTimer(const QString& crstrID, const uint cuintInterval
                                                                           ,const QString& crstrFunction) {
                                              if ( crstrID.trimmed().isEmpty() == true || cuintInterval == 0
                                                || crstrFunction.trimmed().isEmpty() == true
                                                || crstrFunction.indexOf(clsXMLnode::msccScriptDelimiter) == -1 ) {
                                              //One or more of the parameters are invalid, do nothing
                                                  return;
                                              }
                                              //Get Application instance
                                              clsMainWnd* pAppInstance(clsMainWnd::pobjGetAppWnd());
                                              if ( pAppInstance == nullptr ) {
                                              //Cannot get application instance!
                                                  return;
                                              }
                                              //Look for registered timer
                                              QTimer* ptmrScript(pAppInstance->ptmrGetTimer(crstrID));
                                              if ( ptmrScript != nullptr ) {
                                              //Already registered, do nothing
                                                  return;
                                              }
                                              //No timer locatd with that ID, its safe to proceed
                                              QStringList slstScript = crstrFunction.split(clsXMLnode::msccScriptDelimiter);
                                              mpScripts* pmpScriptsMap;
                                              if ( slstScript.length() == SSF_PARAM_COUNT
                                              && (pmpScriptsMap = clsMainWnd::pmpGetScriptsMap()) != nullptr ) {
                                              //Look for the script in the scripts map
                                                  mpScripts::iterator itrScript(pmpScriptsMap->find(slstScript[SFF_FILE_IDX]));
                                                  if ( itrScript != pmpScriptsMap->end() ) {
                                              //Found it, build the script up ready for the signal connection
                                                      QString strScript(itrScript->second);
                                              //Get pointer to script engine
                                                      QJSEngine* pobjScriptEng(clsJSON::pobjGetScriptEng());
                                              //Create new timer
                                                      ptmrScript = new QTimer();
                                                      ptmrScript->setInterval(cuintInterval);
                                              //Register the new timer using the supplied ID
                                                      pAppInstance->registerTimer(ptmrScript, crstrID);
                                              //Add any globals to the script
                                                      clsScriptHelper::pobjGetInstance()->addGlobals(pobjScriptEng);
                                              //Build up script function call
                                                      QString strFile(slstScript[SFF_FILE_IDX])
                                                             ,strCall(slstScript[SSF_FUNCTION_IDX])
                                                             ,strScriptWithCall(strScript)
                                                             ,strFunc(strCall
                                                                    + QString(clsDebugService::msccBrktOpen)
                                                                    + QString(clsDebugService::msccBrktClose)
                                                                    + QString(clsXMLnode::msccScriptFunctionTerminator));
                                                       if ( strScriptWithCall.endsWith(clsXMLnode::msccScriptFunctionTerminator) != true ) {
                                                           strScriptWithCall += clsXMLnode::msccScriptFunctionTerminator;
                                                       }
                                                       strScriptWithCall += strFunc;
                                              //Create connection to timer and script
                                                       QMetaObject::Connection cn = QObject::connect(ptmrScript
                                                                                                   ,&QTimer::timeout
                                                                                                   ,pobjScriptEng
                                                                                                   ,[pobjScriptEng
                                                                                                    ,ptmrScript
                                                                                                    ,strFile
                                                                                                    ,strFunc
                                                                                                    ,strScriptWithCall]() {
                                                           QJSValue objResult(pobjScriptEng->evaluate(strScriptWithCall));
                                                           QString strError;
                                                           if ( objResult.isError() == true ) {
                                                               strError = QString("%1\n%2\n%3").arg(strFile).arg(strFunc)
                                                                                               .arg(objResult.toString());
                                                           } else {
                                                               QString strResult(objResult.toString());
                                                               if ( strResult.compare("undefined") != 0 ) {
                                                                   strError = strResult;
                                                               }
                                                           }
                                                           if ( strError.isEmpty() != true ) {
                                                               clsXMLnode* pobjRoot(clsXMLnode::spobjGetRoot());
                                                               emit pobjRoot->error(strError);
                                                               ptmrScript->deleteLater();
                                                           }
                                                      });
                                                      QThread* pobjScriptEngThread(pobjScriptEng->thread());
                                                      ptmrScript->moveToThread(pobjScriptEngThread);
                                                  }
                                              }
                                          }
                                          /**
                                           * @brief clsScriptHelper::startTimer
                                           * @param crstrID : Constant reference to timer ID
                                           */
                                          void clsScriptHelper::startTimer(const QString& crstrID) {
                                              //Get Application instance
                                              clsMainWnd* pAppInstance(clsMainWnd::pobjGetAppWnd());
                                              if ( pAppInstance == nullptr ) {
                                              //Cannot get application instance!
                                                  return;
                                              }
                                              QTimer* ptmrScript(pAppInstance->ptmrGetTimer(crstrID));
                                              if ( ptmrScript != nullptr ) {
                                                  QTimer::singleShot(0, ptmrScript, [ptmrScript]() { ptmrScript->start(); } );
                                              }
                                          }
                                          

                                          Kind Regards,
                                          Sy

                                          KroMignonK 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