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. Confused by Qt Object Model and QTimer

Confused by Qt Object Model and QTimer

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 4 Posters 1.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.
  • D Offline
    D Offline
    DRoscoe
    wrote on last edited by
    #1

    I'm using a QTimer as a sentinel against drop-out of data from a remote host that isn't the result of a dropped connection. The initialize() slot is tied to the started() signal from the thread in which it resides:

    void TapDisplayCommunicationHandler::initialize()
    {
      heartbeat_timer = new QTimer(this);
      QObject::connect(heartbeat_timer, SIGNAL(timeout()), 
                         this, SLOT(handleHeartbeatTimeout()));
    }
    

    Since this timer is meant to indicate when data flow stops, I don't start it until the actual connection is established:

    void TapDisplayCommunicationHandler::
    signalConnectionEstablished()
    {
      emit connectionEstablished();
      
      // start "heartbeat" timer to wait for data to arrive
      heartbeat_timer->start(10000);
    }
    

    When data arrives, I restart the timer to start the clock over:

    void TapDisplayCommunicationHandler::
      processIncomingData(QDataStream& input_stream)
    {
      // we've received new data before the heartbeat timer timeout.  Reset thetimer
      heartbeat_timer->start();
    
    

    If the timeout() signal hits, I emit an error to my main thread:

    void TapDisplayCommunicationHandler::handleHeartbeatTimeout()
    {
      // don't allow any more timer events
      heartbeat_timer->stop();
    
      // we've stopped receiving data.  Emit an error signal
      emit connectionLost(connection_name);
    }
    

    This implementation presents two problems:

    • I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

    • When/how do I delete this timer? If I call 'delete' from my destructor, the documentation says I could crash my app if there are pending events. If I want to use 'deleteLater()' what signal am I tying it to? Also, how do I delete the last instance of this timer after the event loop stops running? It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped

    kshegunovK JKSHJ VRoninV 3 Replies Last reply
    0
    • D DRoscoe

      I'm using a QTimer as a sentinel against drop-out of data from a remote host that isn't the result of a dropped connection. The initialize() slot is tied to the started() signal from the thread in which it resides:

      void TapDisplayCommunicationHandler::initialize()
      {
        heartbeat_timer = new QTimer(this);
        QObject::connect(heartbeat_timer, SIGNAL(timeout()), 
                           this, SLOT(handleHeartbeatTimeout()));
      }
      

      Since this timer is meant to indicate when data flow stops, I don't start it until the actual connection is established:

      void TapDisplayCommunicationHandler::
      signalConnectionEstablished()
      {
        emit connectionEstablished();
        
        // start "heartbeat" timer to wait for data to arrive
        heartbeat_timer->start(10000);
      }
      

      When data arrives, I restart the timer to start the clock over:

      void TapDisplayCommunicationHandler::
        processIncomingData(QDataStream& input_stream)
      {
        // we've received new data before the heartbeat timer timeout.  Reset thetimer
        heartbeat_timer->start();
      
      

      If the timeout() signal hits, I emit an error to my main thread:

      void TapDisplayCommunicationHandler::handleHeartbeatTimeout()
      {
        // don't allow any more timer events
        heartbeat_timer->stop();
      
        // we've stopped receiving data.  Emit an error signal
        emit connectionLost(connection_name);
      }
      

      This implementation presents two problems:

      • I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

      • When/how do I delete this timer? If I call 'delete' from my destructor, the documentation says I could crash my app if there are pending events. If I want to use 'deleteLater()' what signal am I tying it to? Also, how do I delete the last instance of this timer after the event loop stops running? It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped

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

      Hi,
      @DRoscoe said in Confused by Qt Object Model and QTimer:

      When/how do I delete this timer?

      Well, when is up to you, as to how - use QObject::deleteLater. ;)

      If I want to use 'deleteLater()' what signal am I tying it to?

      I don't follow. You can call slots as functions, because in the end they're just functions.

      It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped.

      All pending delete events are processed before the event loop exits, if that's what you're asking so there's no leak (and you gave it a parent anyway, so no need to worry about the last timer).

      As a side note, why don't you put the timer as an auto-storage (stack) variable in your class and just call QTimer::start, QTimer::stop where appropriate. I don't see any gain in allocating it on the heap in this case.

      Kind regards.

      Read and abide by the Qt Code of Conduct

      D 1 Reply Last reply
      4
      • D DRoscoe

        I'm using a QTimer as a sentinel against drop-out of data from a remote host that isn't the result of a dropped connection. The initialize() slot is tied to the started() signal from the thread in which it resides:

        void TapDisplayCommunicationHandler::initialize()
        {
          heartbeat_timer = new QTimer(this);
          QObject::connect(heartbeat_timer, SIGNAL(timeout()), 
                             this, SLOT(handleHeartbeatTimeout()));
        }
        

        Since this timer is meant to indicate when data flow stops, I don't start it until the actual connection is established:

        void TapDisplayCommunicationHandler::
        signalConnectionEstablished()
        {
          emit connectionEstablished();
          
          // start "heartbeat" timer to wait for data to arrive
          heartbeat_timer->start(10000);
        }
        

        When data arrives, I restart the timer to start the clock over:

        void TapDisplayCommunicationHandler::
          processIncomingData(QDataStream& input_stream)
        {
          // we've received new data before the heartbeat timer timeout.  Reset thetimer
          heartbeat_timer->start();
        
        

        If the timeout() signal hits, I emit an error to my main thread:

        void TapDisplayCommunicationHandler::handleHeartbeatTimeout()
        {
          // don't allow any more timer events
          heartbeat_timer->stop();
        
          // we've stopped receiving data.  Emit an error signal
          emit connectionLost(connection_name);
        }
        

        This implementation presents two problems:

        • I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

        • When/how do I delete this timer? If I call 'delete' from my destructor, the documentation says I could crash my app if there are pending events. If I want to use 'deleteLater()' what signal am I tying it to? Also, how do I delete the last instance of this timer after the event loop stops running? It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped

        JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by
        #3

        @DRoscoe said in Confused by Qt Object Model and QTimer:

        void TapDisplayCommunicationHandler::initialize()
        {
          heartbeat_timer = new QTimer(this);
          ...
        }
        

        In the snippet above, you have set your TapDisplayCommunicationHandler as the parent of the QTimer. Therefore, when you delete your TapDisplayCommunicationHandler, the QTimer will automatically get deleted too. You don't need to do anything else.

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        1 Reply Last reply
        3
        • D DRoscoe

          I'm using a QTimer as a sentinel against drop-out of data from a remote host that isn't the result of a dropped connection. The initialize() slot is tied to the started() signal from the thread in which it resides:

          void TapDisplayCommunicationHandler::initialize()
          {
            heartbeat_timer = new QTimer(this);
            QObject::connect(heartbeat_timer, SIGNAL(timeout()), 
                               this, SLOT(handleHeartbeatTimeout()));
          }
          

          Since this timer is meant to indicate when data flow stops, I don't start it until the actual connection is established:

          void TapDisplayCommunicationHandler::
          signalConnectionEstablished()
          {
            emit connectionEstablished();
            
            // start "heartbeat" timer to wait for data to arrive
            heartbeat_timer->start(10000);
          }
          

          When data arrives, I restart the timer to start the clock over:

          void TapDisplayCommunicationHandler::
            processIncomingData(QDataStream& input_stream)
          {
            // we've received new data before the heartbeat timer timeout.  Reset thetimer
            heartbeat_timer->start();
          
          

          If the timeout() signal hits, I emit an error to my main thread:

          void TapDisplayCommunicationHandler::handleHeartbeatTimeout()
          {
            // don't allow any more timer events
            heartbeat_timer->stop();
          
            // we've stopped receiving data.  Emit an error signal
            emit connectionLost(connection_name);
          }
          

          This implementation presents two problems:

          • I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

          • When/how do I delete this timer? If I call 'delete' from my destructor, the documentation says I could crash my app if there are pending events. If I want to use 'deleteLater()' what signal am I tying it to? Also, how do I delete the last instance of this timer after the event loop stops running? It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          @DRoscoe said in Confused by Qt Object Model and QTimer:

          I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

          Looking at your code you probably want to call heartbeat_timer->setSingleShot(true); so it stops automatically after a timeout.

          @DRoscoe said in Confused by Qt Object Model and QTimer:

          When/how do I delete this timer?

          As mentioned already, since you pass a parent in the constructor, Qt will take care of deleting it

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          D 1 Reply Last reply
          2
          • VRoninV VRonin

            @DRoscoe said in Confused by Qt Object Model and QTimer:

            I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

            Looking at your code you probably want to call heartbeat_timer->setSingleShot(true); so it stops automatically after a timeout.

            @DRoscoe said in Confused by Qt Object Model and QTimer:

            When/how do I delete this timer?

            As mentioned already, since you pass a parent in the constructor, Qt will take care of deleting it

            D Offline
            D Offline
            DRoscoe
            wrote on last edited by
            #5

            @VRonin I considered that, but it doesn't gain me much.

            1 Reply Last reply
            0
            • kshegunovK kshegunov

              Hi,
              @DRoscoe said in Confused by Qt Object Model and QTimer:

              When/how do I delete this timer?

              Well, when is up to you, as to how - use QObject::deleteLater. ;)

              If I want to use 'deleteLater()' what signal am I tying it to?

              I don't follow. You can call slots as functions, because in the end they're just functions.

              It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped.

              All pending delete events are processed before the event loop exits, if that's what you're asking so there's no leak (and you gave it a parent anyway, so no need to worry about the last timer).

              As a side note, why don't you put the timer as an auto-storage (stack) variable in your class and just call QTimer::start, QTimer::stop where appropriate. I don't see any gain in allocating it on the heap in this case.

              Kind regards.

              D Offline
              D Offline
              DRoscoe
              wrote on last edited by
              #6

              @kshegunov Thanks. I took your advice and made it a class attribute.

              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