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.
  • kshegunovK kshegunov

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

    @kshegunov , please see edit of my last post which includes the body of the lambda. The execution doesn't stop, there is just output to the debug.

    I have a fairly good idea where the problem may be, but I prefer not to speculate at this point. If the program doesn't stop and the mentioned environment variable is set, then you're not running your application in debug mode - check this and adjust accordingly.

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

    @kshegunov , 100% I'm in debug, I'm running in Qt Creator debug and developing. I have a function called createTimer here is the prototype:

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

    The implementation:

    /**
     * @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();
        //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
                                                              ,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();
                     }
                });
        //Start the timer
                ptmrScript->start(cuintInterval);
            }
        }
    }
    

    In my JavaScript I call the C++ function:

    xmleng.createTimer("t1", 50, "simon2.js@testTimer");
    

    The JavaScript lambda function, it doesn't get called because the slot doesn't get called:

    function testTimer() {
        //All properties area stored as strings, convert to integer
        var intStageCtr = parseInt(xmleng.getProperty(cstrFormTest, cstrStageCtr));	
        xmleng.log(0, "testTimer[" + intStageCtr + "]", cstrThis, 316);
        //Increment stage counter
        intStageCtr++;
        //Convert back to string and store
        xmleng.setProperty(cstrFormTest, cstrStageCtr, String(intStageCtr));
    }
    

    Kind Regards,
    Sy

    kshegunovK 1 Reply Last reply
    0
    • SPlattenS SPlatten

      @kshegunov , 100% I'm in debug, I'm running in Qt Creator debug and developing. I have a function called createTimer here is the prototype:

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

      The implementation:

      /**
       * @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();
          //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
                                                                ,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();
                       }
                  });
          //Start the timer
                  ptmrScript->start(cuintInterval);
              }
          }
      }
      

      In my JavaScript I call the C++ function:

      xmleng.createTimer("t1", 50, "simon2.js@testTimer");
      

      The JavaScript lambda function, it doesn't get called because the slot doesn't get called:

      function testTimer() {
          //All properties area stored as strings, convert to integer
          var intStageCtr = parseInt(xmleng.getProperty(cstrFormTest, cstrStageCtr));	
          xmleng.log(0, "testTimer[" + intStageCtr + "]", cstrThis, 316);
          //Increment stage counter
          intStageCtr++;
          //Convert back to string and store
          xmleng.setProperty(cstrFormTest, cstrStageCtr, String(intStageCtr));
      }
      
      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #15

      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:

      qDebug() << QThread::currentThread();
      

      Read and abide by the Qt Code of Conduct

      SPlattenS 1 Reply Last reply
      0
      • kshegunovK kshegunov

        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:

        qDebug() << QThread::currentThread();
        
        SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by SPlatten
        #16

        @kshegunov , I've stepped through this logic, I expect the initial call to ptmrGetTimer to return nullptr as on first call the timer won't be registered which it isn't. I've stepped through the logic to the line:

        ptmrScript->start(cuintInterval);
        

        No issues except the slot isn't called when the timer expires. And the mentioned debug output.

        Kind Regards,
        Sy

        kshegunovK 1 Reply Last reply
        0
        • SPlattenS SPlatten

          @kshegunov , I've stepped through this logic, I expect the initial call to ptmrGetTimer to return nullptr as on first call the timer won't be registered which it isn't. I've stepped through the logic to the line:

          ptmrScript->start(cuintInterval);
          

          No issues except the slot isn't called when the timer expires. And the mentioned debug output.

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

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

          @kshegunov , I've stepped through this logic, I expect the initial call to ptmrGetTimer to return nullptr as on first call the timer won't be registered which it isn't.

          I requested something very specific with a very specific purpose. Please do what I asked and provide the output of the mentioned qDebug call.

          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.:

            @kshegunov , I've stepped through this logic, I expect the initial call to ptmrGetTimer to return nullptr as on first call the timer won't be registered which it isn't.

            I requested something very specific with a very specific purpose. Please do what I asked and provide the output of the mentioned qDebug call.

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

            @kshegunov Adding this now. I've actually changed the code to add:

            QThread* pobjCurrThread(QThread::currentThread());
            //Create new timer
            ptmrScript = new QTimer();
            ptmrScript->moveToThread(pobjCurrThread);
            qdbg() << "pobjCurrThread: " << pobjCurrThread;
            

            Output:

            pobjCurrThread: QThread(0x600000269c80)
            

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

            Kind Regards,
            Sy

            kshegunovK 1 Reply Last reply
            0
            • SPlattenS SPlatten

              @kshegunov Adding this now. I've actually changed the code to add:

              QThread* pobjCurrThread(QThread::currentThread());
              //Create new timer
              ptmrScript = new QTimer();
              ptmrScript->moveToThread(pobjCurrThread);
              qdbg() << "pobjCurrThread: " << pobjCurrThread;
              

              Output:

              pobjCurrThread: QThread(0x600000269c80)
              

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

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

              @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]

              Read and abide by the Qt Code of Conduct

              SPlattenS 3 Replies 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
                #20

                @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.

                Kind Regards,
                Sy

                SPlattenS 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
                  #21

                  @kshegunov , this is the modified source:

                              QThread* pobjCurrThread(QThread::currentThread());
                      //Create new timer
                  qdbg() << "Before Timer creation: " << pobjCurrThread;
                              ptmrScript = new QTimer(pobjCurrThread);
                      //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
                  qdbg() << "Before QObject::connect: " << QThread::currentThread();
                  

                  And the resulting output in debug:

                  Before Timer creation: QThread(0x60000026c140)
                  S000000000029E000000010940T08:43:44.084W:QObject: Cannot create children for a parent that is in a different thread.
                  (Parent is QThread(0x60000026c140), parent's thread is QThread(0x600000004180), current thread is QThread(0x60000026c140)
                  S000000000030E000000010940T08:43:44.084DL00000661F../clsScriptHelper.cpp[void clsScriptHelper::createTimer]
                  Before QObject::connect: QThread(0x60000026c140)
                  

                  Kind Regards,
                  Sy

                  1 Reply Last reply
                  0
                  • 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

                                          • Login

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