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. Timer with Lambda function
Forum Updated to NodeBB v4.3 + New Features

Timer with Lambda function

Scheduled Pinned Locked Moved Unsolved General and Desktop
35 Posts 6 Posters 5.8k 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

    @KroMignon , thanks for the advice, I've modified the thread loop to:

    void clsMsgSender::run() {    
        QJsonObject objJSON;
        while( blnAnythingToDo(objJSON) == true ) {
        //Sleep to allow a small cap between transmission
            exec();
            QThread::usleep(100);
        //Look for a module name in the message
            QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType);
    
            if ( itrFound != objJSON.end() ) {
                const QJsonValueRef crobjMsgType = itrFound.value();
                QString strMsgType(crobjMsgType.toString());
    
                if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) {
        //Insert a unique message ID into the message
                    objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID));
        //Create entry to monitor status of this message
                    new clsMsgTrkr(this, objJSON);
                }
            }
        //Writes message to socket
            emit write(objJSON);
        }
        emit queueEmpty();
    }
    

    I've also added a class to replace the original structure:

        class clsMsgTrkr {
        Q_OBJECT
    
        private:
            static const quint16 mscuint16AckTimeout = 5000;
            static mmpAck msmpAcks;
    
            QJsonObject mobjMsg;
            clsMsgSender* mpMsgSndr;
            QTimer mtmrMonitor;
    
        public:
            clsMsgTrkr(clsMsgSender* pMsgSndr, QJsonObject& robjJSON);
            ~clsMsgTrkr();
    
        signals:
            void startTiming();
    
        public slots:
            void onStartTiming();
            void onTimeout();
        };
    

    The implementation:

    //Static initialisation
    mmpAck clsMsgTrkr::msmpAcks;
    /**
     * @brief clsMsgTrkr - Class constructor
     * @param pMsgSndr : Pointer to message sending class
     * @param robjJSON : Reference to JSON message
     */
    clsMsgTrkr::clsMsgTrkr(clsMsgSender* pMsgSndr, QJsonObject& robjJSON) {
        mobjMsg = robjJSON;
        mpMsgSndr = pMsgSndr;
    //Add tracker to list
        clsMsgTrkr::msmpAcks.insert(std::make_pair(clsMsgSender::ulnglngGetMsgID(), this));
    }
    /**
     * @brief clsMsgTrkr::~clsMsgTrkr - Class desctructor
     */
    clsMsgTrkr::~clsMsgTrkr() {
        if ( mtmrMonitor.isActive() ) {
            mtmrMonitor.stop();
        }
    }
    /**
     * @brief clsMsgTrker::onStartTiming
     */
    void clsMsgTrkr::onStartTiming() {
        QObject::connect(&mtmrMonitor, &QTimer::timeout, this, &clsMsgTrkr::onTimeout);
        mtmrMonitor.start(1);//mscuint16AckTimeout);
    }
    /**
     * @brief clsMsgTrkr::onTimeout
     */
    void clsMsgTrkr::onTimeout() {
        qdbg() << "TIMEOUT!";
        //Re-send message
        emit mpMsgSndr->write(mobjMsg);
    }
    

    Its still a work in progress, but I'm struggling with the compile errors:

    ../clsMsgSender.cpp:242:14: note: in instantiation of function template specialization 'QObject::connect<void (QTimer::*)(QTimer::QPrivateSignal), void (clsMsgTrkr::*)()>' requested here
        QObject::connect(&mtmrMonitor, &QTimer::timeout, this, &clsMsgTrkr::onTimeout);
    
    KroMignonK Offline
    KroMignonK Offline
    KroMignon
    wrote on last edited by KroMignon
    #25

    @SPlatten said in Timer with Lambda function:

    class clsMsgTrkr {
    Q_OBJECT

    Does not made sense, do you mean?

    class clsMsgTrkr : public QObject 
    {
         Q_OBJECT
    ...
    };
    

    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
    2
    • KroMignonK KroMignon

      @SPlatten said in Timer with Lambda function:

      class clsMsgTrkr {
      Q_OBJECT

      Does not made sense, do you mean?

      class clsMsgTrkr : public QObject 
      {
           Q_OBJECT
      ...
      };
      
      SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by
      #26

      @KroMignon thank you, that was the problem I originally based the class on QTimer.

      Kind Regards,
      Sy

      KroMignonK 1 Reply Last reply
      0
      • SPlattenS SPlatten

        @KroMignon thank you, that was the problem I originally based the class on QTimer.

        KroMignonK Offline
        KroMignonK Offline
        KroMignon
        wrote on last edited by KroMignon
        #27

        @SPlatten said in Timer with Lambda function:

        thank you, that was the problem I originally based the class on QTimer.

        Sorry, but that is only one of your problems.
        I know, each developer has his own programming style, but you are very confusing.

        You are mixing to many things and subclassing Qt classes which does not really required to be (like QTimer and QThread).

        And calling exec() in the run() slot will of course start the QEventLoop. But, all code after exec() will be executed on QEventLoop end!.

        There are so many errors, I don't know where to start.
        Sorry but please read this to understand how to use threads with Qt:

        • https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
        • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
        • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-2/

        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 2 Replies Last reply
        5
        • KroMignonK KroMignon

          @SPlatten said in Timer with Lambda function:

          thank you, that was the problem I originally based the class on QTimer.

          Sorry, but that is only one of your problems.
          I know, each developer has his own programming style, but you are very confusing.

          You are mixing to many things and subclassing Qt classes which does not really required to be (like QTimer and QThread).

          And calling exec() in the run() slot will of course start the QEventLoop. But, all code after exec() will be executed on QEventLoop end!.

          There are so many errors, I don't know where to start.
          Sorry but please read this to understand how to use threads with Qt:

          • https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
          • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
          • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-2/
          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #28

          @KroMignon , ok thank you.

          Kind Regards,
          Sy

          1 Reply Last reply
          0
          • KroMignonK KroMignon

            @SPlatten said in Timer with Lambda function:

            thank you, that was the problem I originally based the class on QTimer.

            Sorry, but that is only one of your problems.
            I know, each developer has his own programming style, but you are very confusing.

            You are mixing to many things and subclassing Qt classes which does not really required to be (like QTimer and QThread).

            And calling exec() in the run() slot will of course start the QEventLoop. But, all code after exec() will be executed on QEventLoop end!.

            There are so many errors, I don't know where to start.
            Sorry but please read this to understand how to use threads with Qt:

            • https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
            • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
            • http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-2/
            SPlattenS Offline
            SPlattenS Offline
            SPlatten
            wrote on last edited by SPlatten
            #29

            @KroMignon , I've just been reading the links that you posted.

            The first link is interesting in the it states: "Right because QThreads are in fact quite easy to use, as long as you ignore the incorrect official Qt documentation on QThread"

            I've been modifying some of my threads based on this information. The second link shows illustrations Usage 1-1 which is identical to the way I've implemented a class derived from QThread that does not call exec in the run function.

            I'm still reading and working through the documentation.

            Kind Regards,
            Sy

            KroMignonK 1 Reply Last reply
            0
            • SPlattenS SPlatten

              @KroMignon , I've just been reading the links that you posted.

              The first link is interesting in the it states: "Right because QThreads are in fact quite easy to use, as long as you ignore the incorrect official Qt documentation on QThread"

              I've been modifying some of my threads based on this information. The second link shows illustrations Usage 1-1 which is identical to the way I've implemented a class derived from QThread that does not call exec in the run function.

              I'm still reading and working through the documentation.

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by
              #30

              @SPlatten said in Timer with Lambda function:

              I'm still reading and working through the documentation.

              Great to see that you are starting reading documentation.

              What you should learn is that subclassing QThread (or QTimer) is in 99.9% case a nonsense, there are absolut no benefit.
              It is even more easy to create a worker class and move the instance to the dedicated thread.

              One reason is that QThread is a QObject which is holding a thread. So the QThread signals/slots are "living" in the thread in which the QThread instance has been created. But the QObject which are moved to the QThread instance are living in the holded thread.

              Another reason is that you could use the worker in current thread or in a dedicated thread without having to do any change.

              Try to think simple, things becomes complex quickly enough!

              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 Christian EhrlicherC 2 Replies Last reply
              2
              • KroMignonK KroMignon

                @SPlatten said in Timer with Lambda function:

                I'm still reading and working through the documentation.

                Great to see that you are starting reading documentation.

                What you should learn is that subclassing QThread (or QTimer) is in 99.9% case a nonsense, there are absolut no benefit.
                It is even more easy to create a worker class and move the instance to the dedicated thread.

                One reason is that QThread is a QObject which is holding a thread. So the QThread signals/slots are "living" in the thread in which the QThread instance has been created. But the QObject which are moved to the QThread instance are living in the holded thread.

                Another reason is that you could use the worker in current thread or in a dedicated thread without having to do any change.

                Try to think simple, things becomes complex quickly enough!

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

                @KroMignon said in Timer with Lambda function:

                QThread

                Here is my new implementation of my debugging thread:

                if ( clsDebugService::mspThread == nullptr ) {
                        clsDebugService::mspThread = new QThread;
                        moveToThread(clsDebugService::mspThread);
                        //connect(this, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
                        connect(clsDebugService::mspThread, SIGNAL(started()), this, SLOT(process()));
                        //connect(this, SIGNAL(finished()), clsDebugService::mspThread, SLOT(quit()));
                        connect(this, SIGNAL(finished()), this, SLOT(cleanup()));
                        clsDebugService::mspThread->start();
                }
                

                mspThread is a static member of the class clsDebugService, clsDebugService is derived from QObject.

                The cleanup slot:

                void clsDebugService::cleanup() {
                    if ( clsDebugService::mspThread != nullptr ) {
                        if ( clsDebugService::mspThread->isFinished() != true ) {
                            clsDebugService::mspThread->quit();
                        }
                        delete clsDebugService::mspThread;
                        clsDebugService::mspThread = nullptr;
                    }
                }
                

                The process slot:

                void clsDebugService::process() {
                    QString strData, strPath(clsDebugService::strGetUserFolder());
                    clsDebugService* pService = clsDebugService::pGetService();
                
                    while ( pService != nullptr ) {
                        {
                    //Anything on the stack?
                            QMutexLocker lock(&pService->mMutex);
                
                            if ( pService->mStack.size() == 0 ) {
                    //Nothing on the stack, terminate thread
                                break;
                            }
                            strData = pService->mStack.pop();
                        }
                        if ( strData.isEmpty() == true ) {
                            continue;
                        }
                        QStringList slstLines = strData.split("\n");
                        strData = "";
                    //+2 to allow for type prefix and colon
                        QString strPadding(" ");
                        strPadding = strPadding.repeated(clsDebugService::mscintSeqNoLength + 2);
                        uint16_t uint16Line = 1;
                        foreach( QString strLine, slstLines ) {
                            if ( uint16Line++ > 1 ) {
                    //Insert padding at the front of additional lines
                                strLine = strPadding + strLine;
                            }
                            bool blnToFile;
                            if ( pService->blnToFile(blnToFile) == true && blnToFile == true ) {
                                bool blnAutoFileName, blnOpen;
                                if ( pService->blnAutoFileName(blnAutoFileName) != true ) {
                                    blnAutoFileName = false;
                                }
                                if ( blnAutoFileName == true ) {
                                    QChar qcPadding('0'), qcSeperator(QDir::separator());
                                    QDate dtNow(QDate::currentDate());
                                    int intBase(10), intYear(dtNow.year()), intMonth(dtNow.month()), intDay(dtNow.day());
                    //Generate file name using year, month, day
                                    QString strExisting, strFileName = QString("%1%2%3%4").arg(mstrPrefix)
                                                                            .arg(intYear, 4, intBase, qcPadding)
                                                                            .arg(intMonth, 2, intBase, qcPadding)
                                                                            .arg(intDay, 2, intBase, qcPadding);
                                    pService->blnFileName(strExisting);
                
                    //Is file open and is the size greater than the limit?
                                    qint64 int64FileSize;
                
                                    if ( pService->blnIsFileOpen(blnOpen) == true
                                      && blnOpen == true
                                      && pService->blnFileSize(int64FileSize) == true
                                      && int64FileSize > pService->mcint64FileSizeLimit ) {
                    //Increment part number
                                        pService->muint8PartNumber++;
                                    }
                                    if ( blnOpen == true ) {
                    //Get just the file name
                                        int intFile = strExisting.lastIndexOf(qcSeperator);
                                        strExisting = strExisting.mid(intFile + 1);
                    //Remove the extension
                                        strExisting = strExisting.mid(0, strExisting.indexOf("."));
                                    }
                                    if ( blnOpen != true || strExisting.compare(strFileName) != 0 ) {
                                        if ( blnOpen == true ) {
                                            pService->blnFileClose();
                                            blnOpen = false;
                                        }
                                        pService->muint8PartNumber = 1;
                                    }
                    //Append part number
                                    if ( blnOpen != true ) {
                                        pService->blnSetFileName(strPath
                                                               + strFileName
                                                               + QString(".%1.log")
                                                               .arg(pService->muint8PartNumber
                                                                   ,3, intBase, qcPadding));
                                    }
                                }
                    //Is file open?
                                if ( pService->blnIsFileOpen(blnOpen) == true && blnOpen != true ) {
                                    pService->blnOpenFile(blnOpen);
                                }
                                if ( blnOpen == true ) {
                                    QTextStream ts(&pService->mFile);
                                    ts << strLine.toLatin1().data() << "\r\n";
                                }
                            }
                            bool blnToConsole;
                            if ( pService->blnToConsole(blnToConsole) == true && blnToConsole == true ) {
                    //Output to console
                                std::cout << strLine.toLatin1().data() << "\n";
                                std::cout << std::flush;
                            }
                        }
                    }
                    emit finished();
                }
                

                The problem I'm getting not is that as soon as the finished signal is emitted, the application halts on:

                std::abort();
                

                line 1914 of qlogging.cpp, is there anything I've done wrong here? I think the issue is because the thread hadn't finished before it was deleted...

                I am reading up on how to properly wait until it is stopped. Changed connections to:

                connect(clsDebugService::mspThread, &QThread::started
                                            ,this, &clsDebugService::process);
                connect(this, &clsDebugService::finished
                                            ,clsDebugService::mspThread, &QThread::quit);
                connect(clsDebugService::mspThread, &QThread::finished
                                            ,this, &clsDebugService::cleanup);
                

                For some reason when I look at the stack tract I see:

                 qFatal("QThread: Destroyed while thread is still running");
                

                Kind Regards,
                Sy

                KroMignonK 1 Reply Last reply
                0
                • SPlattenS SPlatten

                  @KroMignon said in Timer with Lambda function:

                  QThread

                  Here is my new implementation of my debugging thread:

                  if ( clsDebugService::mspThread == nullptr ) {
                          clsDebugService::mspThread = new QThread;
                          moveToThread(clsDebugService::mspThread);
                          //connect(this, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
                          connect(clsDebugService::mspThread, SIGNAL(started()), this, SLOT(process()));
                          //connect(this, SIGNAL(finished()), clsDebugService::mspThread, SLOT(quit()));
                          connect(this, SIGNAL(finished()), this, SLOT(cleanup()));
                          clsDebugService::mspThread->start();
                  }
                  

                  mspThread is a static member of the class clsDebugService, clsDebugService is derived from QObject.

                  The cleanup slot:

                  void clsDebugService::cleanup() {
                      if ( clsDebugService::mspThread != nullptr ) {
                          if ( clsDebugService::mspThread->isFinished() != true ) {
                              clsDebugService::mspThread->quit();
                          }
                          delete clsDebugService::mspThread;
                          clsDebugService::mspThread = nullptr;
                      }
                  }
                  

                  The process slot:

                  void clsDebugService::process() {
                      QString strData, strPath(clsDebugService::strGetUserFolder());
                      clsDebugService* pService = clsDebugService::pGetService();
                  
                      while ( pService != nullptr ) {
                          {
                      //Anything on the stack?
                              QMutexLocker lock(&pService->mMutex);
                  
                              if ( pService->mStack.size() == 0 ) {
                      //Nothing on the stack, terminate thread
                                  break;
                              }
                              strData = pService->mStack.pop();
                          }
                          if ( strData.isEmpty() == true ) {
                              continue;
                          }
                          QStringList slstLines = strData.split("\n");
                          strData = "";
                      //+2 to allow for type prefix and colon
                          QString strPadding(" ");
                          strPadding = strPadding.repeated(clsDebugService::mscintSeqNoLength + 2);
                          uint16_t uint16Line = 1;
                          foreach( QString strLine, slstLines ) {
                              if ( uint16Line++ > 1 ) {
                      //Insert padding at the front of additional lines
                                  strLine = strPadding + strLine;
                              }
                              bool blnToFile;
                              if ( pService->blnToFile(blnToFile) == true && blnToFile == true ) {
                                  bool blnAutoFileName, blnOpen;
                                  if ( pService->blnAutoFileName(blnAutoFileName) != true ) {
                                      blnAutoFileName = false;
                                  }
                                  if ( blnAutoFileName == true ) {
                                      QChar qcPadding('0'), qcSeperator(QDir::separator());
                                      QDate dtNow(QDate::currentDate());
                                      int intBase(10), intYear(dtNow.year()), intMonth(dtNow.month()), intDay(dtNow.day());
                      //Generate file name using year, month, day
                                      QString strExisting, strFileName = QString("%1%2%3%4").arg(mstrPrefix)
                                                                              .arg(intYear, 4, intBase, qcPadding)
                                                                              .arg(intMonth, 2, intBase, qcPadding)
                                                                              .arg(intDay, 2, intBase, qcPadding);
                                      pService->blnFileName(strExisting);
                  
                      //Is file open and is the size greater than the limit?
                                      qint64 int64FileSize;
                  
                                      if ( pService->blnIsFileOpen(blnOpen) == true
                                        && blnOpen == true
                                        && pService->blnFileSize(int64FileSize) == true
                                        && int64FileSize > pService->mcint64FileSizeLimit ) {
                      //Increment part number
                                          pService->muint8PartNumber++;
                                      }
                                      if ( blnOpen == true ) {
                      //Get just the file name
                                          int intFile = strExisting.lastIndexOf(qcSeperator);
                                          strExisting = strExisting.mid(intFile + 1);
                      //Remove the extension
                                          strExisting = strExisting.mid(0, strExisting.indexOf("."));
                                      }
                                      if ( blnOpen != true || strExisting.compare(strFileName) != 0 ) {
                                          if ( blnOpen == true ) {
                                              pService->blnFileClose();
                                              blnOpen = false;
                                          }
                                          pService->muint8PartNumber = 1;
                                      }
                      //Append part number
                                      if ( blnOpen != true ) {
                                          pService->blnSetFileName(strPath
                                                                 + strFileName
                                                                 + QString(".%1.log")
                                                                 .arg(pService->muint8PartNumber
                                                                     ,3, intBase, qcPadding));
                                      }
                                  }
                      //Is file open?
                                  if ( pService->blnIsFileOpen(blnOpen) == true && blnOpen != true ) {
                                      pService->blnOpenFile(blnOpen);
                                  }
                                  if ( blnOpen == true ) {
                                      QTextStream ts(&pService->mFile);
                                      ts << strLine.toLatin1().data() << "\r\n";
                                  }
                              }
                              bool blnToConsole;
                              if ( pService->blnToConsole(blnToConsole) == true && blnToConsole == true ) {
                      //Output to console
                                  std::cout << strLine.toLatin1().data() << "\n";
                                  std::cout << std::flush;
                              }
                          }
                      }
                      emit finished();
                  }
                  

                  The problem I'm getting not is that as soon as the finished signal is emitted, the application halts on:

                  std::abort();
                  

                  line 1914 of qlogging.cpp, is there anything I've done wrong here? I think the issue is because the thread hadn't finished before it was deleted...

                  I am reading up on how to properly wait until it is stopped. Changed connections to:

                  connect(clsDebugService::mspThread, &QThread::started
                                              ,this, &clsDebugService::process);
                  connect(this, &clsDebugService::finished
                                              ,clsDebugService::mspThread, &QThread::quit);
                  connect(clsDebugService::mspThread, &QThread::finished
                                              ,this, &clsDebugService::cleanup);
                  

                  For some reason when I look at the stack tract I see:

                   qFatal("QThread: Destroyed while thread is still running");
                  
                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #32

                  @SPlatten said in Timer with Lambda function:

                  For some reason when I look at the stack tract I see:

                  As I wrote before, QThread is a QObject which is managing a thread. You should never use delete with a QObject instance but use QObject::deleteLater() which will ensure instance will be deleted in his working thread.

                  I would suggest you to change clsDebugService::cleanup():

                  void clsDebugService::cleanup() {
                      if(clsDebugService::mspThread)
                          clsDebugService::mspThread->deleteLater();
                      clsDebugService::mspThread = nullptr;
                  }
                  

                  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 said in Timer with Lambda function:

                    For some reason when I look at the stack tract I see:

                    As I wrote before, QThread is a QObject which is managing a thread. You should never use delete with a QObject instance but use QObject::deleteLater() which will ensure instance will be deleted in his working thread.

                    I would suggest you to change clsDebugService::cleanup():

                    void clsDebugService::cleanup() {
                        if(clsDebugService::mspThread)
                            clsDebugService::mspThread->deleteLater();
                        clsDebugService::mspThread = nullptr;
                    }
                    
                    SPlattenS Offline
                    SPlattenS Offline
                    SPlatten
                    wrote on last edited by SPlatten
                    #33

                    @KroMignon after calling deleteLater is it still ok to set mspThread to nullptr ?

                    I've changed the clean up to:

                        if ( clsDebugService::mspThread != nullptr ) {
                            clsDebugService::mspThread->deleteLater();
                            clsDebugService::mspThread = nullptr;
                        }
                    

                    Now I'm seeing in the Application Output:

                    QObject::moveToThread: Current thread (0x101e67a70) is not the object's thread (0x0).
                    Cannot move to target thread (0x101e91530)
                    
                    You might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
                    

                    When all the debug messages have been displayed, a new debug message will cause the thread to be created again, I think this is what causes the above message.

                    Is it because the moveToThread function is called again for the same class again?

                    Ok, I've fixed it, I don't allow the thread to be deleted at all, until the application is terminated, all I do now is restart the thread as long as the thread ptr exists.

                    Kind Regards,
                    Sy

                    1 Reply Last reply
                    0
                    • KroMignonK KroMignon

                      @SPlatten said in Timer with Lambda function:

                      I'm still reading and working through the documentation.

                      Great to see that you are starting reading documentation.

                      What you should learn is that subclassing QThread (or QTimer) is in 99.9% case a nonsense, there are absolut no benefit.
                      It is even more easy to create a worker class and move the instance to the dedicated thread.

                      One reason is that QThread is a QObject which is holding a thread. So the QThread signals/slots are "living" in the thread in which the QThread instance has been created. But the QObject which are moved to the QThread instance are living in the holded thread.

                      Another reason is that you could use the worker in current thread or in a dedicated thread without having to do any change.

                      Try to think simple, things becomes complex quickly enough!

                      Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #34

                      @KroMignon said in Timer with Lambda function:

                      Great to see that you are starting reading documentation.

                      ROFL

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        SimonSchroeder
                        wrote on last edited by
                        #35

                        I usually just call exit() on the thread to stop the event loop, i.e. clsDebugService::mspThread->exit() in your case. Then there is some special quirk with QThreads: You can connect the thread's finished signal with the thread's deleteLater slot. Before the event loop actually stops it will first still handle the deleteLater slot for the thread:

                        connect(clsDebugService::mspThread, &QThread::finished, clsDebugService::mspThread, &QThread::deleteLater);
                        

                        This is how you can clean up the thread once your done.

                        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