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. QTimer does not fire slot
Forum Updated to NodeBB v4.3 + New Features

QTimer does not fire slot

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtimer failed
6 Posts 2 Posters 1.3k Views 1 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.
  • U Offline
    U Offline
    ulix
    wrote on last edited by
    #1

    I have a QTimer * I allocate in a function running in a thread.
    In the same function, I connect its timeout signal to a slot, then I set it as a single shot timer and start it.
    Next, I call another function and sleep for a while waiting for the timer to expire and call the slot. The timer expires but the slot never gets called, by the way if a I call QCoreApplication::processEvents(); after the sleep time the slot gets called.
    I do not understand this behavior and I do not know how obviate to this problem without calling the processEvents

    Thank you in advance

    JonBJ 1 Reply Last reply
    0
    • U ulix

      I have a QTimer * I allocate in a function running in a thread.
      In the same function, I connect its timeout signal to a slot, then I set it as a single shot timer and start it.
      Next, I call another function and sleep for a while waiting for the timer to expire and call the slot. The timer expires but the slot never gets called, by the way if a I call QCoreApplication::processEvents(); after the sleep time the slot gets called.
      I do not understand this behavior and I do not know how obviate to this problem without calling the processEvents

      Thank you in advance

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @ulix
      Show your code. You may have a threading issue. Qt timers only cause timeout signal to call slot if event loop is running. Don't know what your "sleep" is, likely to block the event loop? E.g. if you call sleep() that is not going to get interrupted by a QTimer timeout.

      U 1 Reply Last reply
      4
      • JonBJ JonB

        @ulix
        Show your code. You may have a threading issue. Qt timers only cause timeout signal to call slot if event loop is running. Don't know what your "sleep" is, likely to block the event loop? E.g. if you call sleep() that is not going to get interrupted by a QTimer timeout.

        U Offline
        U Offline
        ulix
        wrote on last edited by
        #3

        @JonB The code is:

        void FWCommissioningTask::runTask()
        {
             ...
            if (!GetGwMgr->executeFirmwareCommissioning(identifier, commissioning.path, end_points)) {
                ...
                }
        
            _task_mutex.lock();
            _task_condition.wait(&_task_mutex);
        
            return;
        }
        
        bool GWMgr::executeFirmwareCommissioning(QString identifier, QString commissioningPath, QList<QString> endPoints)
        {
        
            return mOTAUpdateMgr.executeFirmwareCommissioning(identifier, commissioningPath, endPoints);
        }
        
        bool OTAUpdateMgr::executeFirmwareCommissioning(QString id, QString fwPath, QList<QString> MACs)
        {
            ...
            _evaluate_fsm_state_actions(OTAUpdateFSMState::commissioning);
        
            return true;
        }
        
        void OTAUpdateMgr::_evaluate_fsm_state_actions(const OTAUpdateFSMState state)
        {
        
            switch (state) {
             ...
        
            case OTAUpdateFSMState::commissioning:
                _init_commissioning_phase();
                _launch_commissioning_phase();
                break;
        
            case OTAUpdateFSMState::confirmed:
                 if (_init_confirmed_state()) {
                    _launch_confirmed_actions();
                 } else {
                    _evaluate_fsm_state_actions(OTAUpdateFSMState::error);
                 }
                break;
                ...
            }
        }
        
        bool OTAUpdateMgr::_init_commissioning_phase()
        {
            ...
            return true;
        }
        
        bool OTAUpdateMgr::_launch_commissioning_phase()
        {
            if (_first_message_timer == nullptr) {
                _first_message_timer = new QTimer();
            }
        
            for(auto nodeData: m_FSM.nodes) {
                ...
                if (!_first_message_timer->isActive()) {
                    connect(_first_message_timer, &QTimer::timeout,
                            this, &OTAUpdateMgr::_on_first_message_espiration);
                    _first_message_timer->setSingleShot(true);
                     ...
                    _first_message_timer->start(sleep_time);
                }
            }
            _evaluate_fsm_state_actions(OTAUpdateFSMState::confirmed);
            return true;
        }
        
        void OTAUpdateMgr::_on_first_message_espiration()
        {
           ...
        }
        

        Notice the runTask is the entry point of a thread where all starts

        JonBJ 1 Reply Last reply
        0
        • U ulix

          @JonB The code is:

          void FWCommissioningTask::runTask()
          {
               ...
              if (!GetGwMgr->executeFirmwareCommissioning(identifier, commissioning.path, end_points)) {
                  ...
                  }
          
              _task_mutex.lock();
              _task_condition.wait(&_task_mutex);
          
              return;
          }
          
          bool GWMgr::executeFirmwareCommissioning(QString identifier, QString commissioningPath, QList<QString> endPoints)
          {
          
              return mOTAUpdateMgr.executeFirmwareCommissioning(identifier, commissioningPath, endPoints);
          }
          
          bool OTAUpdateMgr::executeFirmwareCommissioning(QString id, QString fwPath, QList<QString> MACs)
          {
              ...
              _evaluate_fsm_state_actions(OTAUpdateFSMState::commissioning);
          
              return true;
          }
          
          void OTAUpdateMgr::_evaluate_fsm_state_actions(const OTAUpdateFSMState state)
          {
          
              switch (state) {
               ...
          
              case OTAUpdateFSMState::commissioning:
                  _init_commissioning_phase();
                  _launch_commissioning_phase();
                  break;
          
              case OTAUpdateFSMState::confirmed:
                   if (_init_confirmed_state()) {
                      _launch_confirmed_actions();
                   } else {
                      _evaluate_fsm_state_actions(OTAUpdateFSMState::error);
                   }
                  break;
                  ...
              }
          }
          
          bool OTAUpdateMgr::_init_commissioning_phase()
          {
              ...
              return true;
          }
          
          bool OTAUpdateMgr::_launch_commissioning_phase()
          {
              if (_first_message_timer == nullptr) {
                  _first_message_timer = new QTimer();
              }
          
              for(auto nodeData: m_FSM.nodes) {
                  ...
                  if (!_first_message_timer->isActive()) {
                      connect(_first_message_timer, &QTimer::timeout,
                              this, &OTAUpdateMgr::_on_first_message_espiration);
                      _first_message_timer->setSingleShot(true);
                       ...
                      _first_message_timer->start(sleep_time);
                  }
              }
              _evaluate_fsm_state_actions(OTAUpdateFSMState::confirmed);
              return true;
          }
          
          void OTAUpdateMgr::_on_first_message_espiration()
          {
             ...
          }
          

          Notice the runTask is the entry point of a thread where all starts

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @ulix
          Are you expecting the single shot timer to timeout while runTask() is waiting on _task_condition.wait(&_task_mutex);? It won't.

          Separately: since you go new QTimer() without passing this as parent does your destructor delete this->_first_message_timer? Or it seems to me simpler to put the QTimer as a member variable without the pointer/new so it does not need freeing.

          U 1 Reply Last reply
          0
          • JonBJ JonB

            @ulix
            Are you expecting the single shot timer to timeout while runTask() is waiting on _task_condition.wait(&_task_mutex);? It won't.

            Separately: since you go new QTimer() without passing this as parent does your destructor delete this->_first_message_timer? Or it seems to me simpler to put the QTimer as a member variable without the pointer/new so it does not need freeing.

            U Offline
            U Offline
            ulix
            wrote on last edited by
            #5

            @JonB
            I removed the mutex and the wait condition by temporarily substituting with a while but the behavior is the same: the timer expires but the slot is never invoked.
            I do not know what to do

            JonBJ 1 Reply Last reply
            0
            • U ulix

              @JonB
              I removed the mutex and the wait condition by temporarily substituting with a while but the behavior is the same: the timer expires but the slot is never invoked.
              I do not know what to do

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @ulix
              You have a QTimer in a thread which does not run the Qt event loop, does it? So no signals will be delivered. Hence your finding:

              The timer expires but the slot never gets called, by the way if a I call QCoreApplication::processEvents(); after the sleep time the slot gets called.

              That processEvents() is the first time the evet loop is invoked. Your thread needs to be running the event loop all the time if that's where the timer is ticking (unless you move the timer to the main UI thread). See QThread::run() & QThread::exec().

              1 Reply Last reply
              3

              • Login

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