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

Timer with Lambda function

Scheduled Pinned Locked Moved Unsolved General and Desktop
35 Posts 6 Posters 5.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SPlattenS SPlatten

    I added a call after call:

    start();
    qdbg() << this->isActive();
    

    qdbg is just a macro I use which is:

    #define qdbg()      qDebug().noquote().nospace()
    

    In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.

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

    @SPlatten said in Timer with Lambda function:

    In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.

    Do you have a forever loop in your code or do you use QThread::sleep()?
    Are you sure QEventLoop of the used thread is working?

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

      @SPlatten said in Timer with Lambda function:

      In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.

      Do you have a forever loop in your code or do you use QThread::sleep()?
      Are you sure QEventLoop of the used thread is working?

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

      @KroMignon, the message transmission is in a thread and there very short sleep in the thread loop:

      void clsMsgSender::run() {    
          QJsonObject objJSON;
          while( blnAnythingToDo(objJSON) == true ) {
          //Sleep to allow a small cap between transmission
              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();
      }
      

      Kind Regards,
      Sy

      jsulmJ KroMignonK 2 Replies Last reply
      0
      • SPlattenS SPlatten

        @KroMignon, the message transmission is in a thread and there very short sleep in the thread loop:

        void clsMsgSender::run() {    
            QJsonObject objJSON;
            while( blnAnythingToDo(objJSON) == true ) {
            //Sleep to allow a small cap between transmission
                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();
        }
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #15

        @SPlatten You expect this to work?

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        SPlattenS 1 Reply Last reply
        0
        • jsulmJ jsulm

          @SPlatten You expect this to work?

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

          @jsulm , ok, perhaps I'm to close to see the obvious, what have I done wrong? Its not complete yet, I haven't finished the code yet, but is there something that would explain why the timer isn't working?

          Kind Regards,
          Sy

          1 Reply Last reply
          0
          • SPlattenS SPlatten

            @KroMignon, the message transmission is in a thread and there very short sleep in the thread loop:

            void clsMsgSender::run() {    
                QJsonObject objJSON;
                while( blnAnythingToDo(objJSON) == true ) {
                //Sleep to allow a small cap between transmission
                    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();
            }
            
            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on last edited by KroMignon
            #17

            @SPlatten I've told you many times to read basic Qt documentation.

            this cannot work!!!

            First, I suppose clsMsgSender is subclassing QThread. And you have create your own run() implementation. So there is no running QEventLoop. This means, all QObject which are running in this thread can NOT receive/emit signals.

            Second, you have a forever loop, so even if there where a running QEventLoop, it will not be called!

            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've told you many times to read basic Qt documentation.

              this cannot work!!!

              First, I suppose clsMsgSender is subclassing QThread. And you have create your own run() implementation. So there is no running QEventLoop. This means, all QObject which are running in this thread can NOT receive/emit signals.

              Second, you have a forever loop, so even if there where a running QEventLoop, it will not be called!

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

              @KroMignon , I'm impatient, I know there is benefit from reading the documentation, I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation.

              Kind Regards,
              Sy

              KroMignonK jsulmJ 2 Replies Last reply
              0
              • SPlattenS SPlatten

                @KroMignon , I'm impatient, I know there is benefit from reading the documentation, I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation.

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

                @SPlatten said in Timer with Lambda function:

                I'm impatient,

                Perhaps you are impatient, but in fact you are losing days doing nonsense code which not working.
                If that is the best way to work, I am pretty sure NO.

                Reading this document would take you 1 or 2 hours, how many hours have you spend to create those non working code?

                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
                2
                • SPlattenS SPlatten

                  @KroMignon , I'm impatient, I know there is benefit from reading the documentation, I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation.

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #20

                  @SPlatten said in Timer with Lambda function:

                  I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation

                  So, instead you waste your time here?
                  I really don't get the logic...

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  1
                  • SPlattenS Offline
                    SPlattenS Offline
                    SPlatten
                    wrote on last edited by
                    #21

                    The logic is I was I was hoping this would be quicker...obviously wrong, no worries, I will read the documentation.

                    Kind Regards,
                    Sy

                    KroMignonK 1 Reply Last reply
                    0
                    • SPlattenS SPlatten

                      The logic is I was I was hoping this would be quicker...obviously wrong, no worries, I will read the documentation.

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

                      @SPlatten said in Timer with Lambda function:

                      The logic is I was I was hoping this would be quicker...obviously wrong, no worries, I will read the documentation.

                      The point is not to read all Qt documentation, but at least the basics to understand how Qt is working.
                      There are very basic notion to know.
                      This will help you to right build your software and to take advantage of Qt architecture.

                      And, as Qt is a asynchronous framework, most of the time you don't have to create threads.
                      One thing is very important, never look thread this also locks the QEventLoop and break major Qt feature ==> signals/slots handling.

                      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:

                        The logic is I was I was hoping this would be quicker...obviously wrong, no worries, I will read the documentation.

                        The point is not to read all Qt documentation, but at least the basics to understand how Qt is working.
                        There are very basic notion to know.
                        This will help you to right build your software and to take advantage of Qt architecture.

                        And, as Qt is a asynchronous framework, most of the time you don't have to create threads.
                        One thing is very important, never look thread this also locks the QEventLoop and break major Qt feature ==> signals/slots handling.

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

                        @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);
                        

                        Kind Regards,
                        Sy

                        JonBJ KroMignonK 2 Replies Last reply
                        0
                        • 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);
                          
                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #24

                          @SPlatten
                          If I'm not mistaken, you have not pasted the line before (or maybe after) the one you quote, which says what the actual error is.....

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

                                          • Login

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