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

    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 Offline
            JonBJ Offline
            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
                        • SPlattenS SPlatten

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

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

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

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

                          Before doing the connect for the timer timeout. Provide the following things (in one post please):

                          1. The whole source of the enclosing function.
                          2. The call stack.
                          3. The output of this added just before doing the connect:
                          qDebug() << ptmrScript->thread() << QThread::currentThread() << ptmrScript->parent();
                          

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          0
                          • SPlattenS SPlatten

                            @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(); } );
                                }
                            }
                            
                            KroMignonK Offline
                            KroMignonK Offline
                            KroMignon
                            wrote on last edited by
                            #43

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

                            right now before trying your suggestion the output is:

                               setupForm() !!!!
                               S000000000029E000000003405T09:32:06.594W:QObject::startTimer: Timers cannot be started from another thread
                            

                            Same issue, you are trying to start a QTimer from the wrong thread.
                            QTimer::singleShot(0, myTimer, [myTimer]() { myTimer->start(); } ); will solve this.

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

                            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