Results 1 to 5 of 5

Thread: qtimer and signal

  1. #1
    Join Date
    Mar 2010
    Location
    spain
    Posts
    25
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default qtimer and signal

    Qt Code:
    1. Stream::Stream(QWidget *parent) :
    2. QObject(parent)
    3. {
    4.  
    5. Timer = new QTimer();
    6. connect(Timer, SIGNAL(timeout()), this, SLOT(Update()));
    7. Timer->start(30);
    8. }
    9.  
    10.  
    11.  
    12. void Stream::Update(){
    13. ActualizarContadores();
    14.  
    15. if (IsFinal(streamUltimo)){
    16. Timer->stop();
    17. if(!Timer->isActive ()){
    18.  
    19. emit Finish();
    20.  
    21. }
    22.  
    23. }
    24.  
    25. }
    To copy to clipboard, switch view to plain text mode 


    Depending on OS and Hardware Finish signal () is issued more than once, ie on windows vista once it is issued is the idea of ​​2 or more consecutive xp.
    Is there a mechanism to ensure that the signal is issued only once?

    thanks

  2. #2
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: qtimer and signal

    It's probably because of whatever happens in the Update() before Timer->stop() takes longer than 30ms and timer fires again while Update is being processed.
    Try this:
    Qt Code:
    1. void Stream::Update()
    2. {
    3. ActualizarContadores();
    4.  
    5. if ( IsFinal( streamUltimo ) )
    6. {
    7. if( Timer->isActive() )
    8. {
    9. Timer->stop();
    10. emit Finish();
    11. }
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 
    Now finish should be emitted only once, but there's no guarantee that the timer won't fire again because of how long it takes to Update().

    Btw the check you make in line #17 doesn't make any sense as it's always true.

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,315
    Thanks
    314
    Thanked 870 Times in 857 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qtimer and signal

    If you only need the timer to fire once, then use this in the constructor:

    Qt Code:
    1. Stream::Stream(QWidget *parent) : QObject(parent)
    2. {
    3. QTimer::singleShot( 30, this, SLOT( Update() ) );
    4. }
    To copy to clipboard, switch view to plain text mode 

    No need to create a QTimer instance if you don't intend to reuse it. Your slot then becomes simply:

    Qt Code:
    1. void Stream::Update()
    2. {
    3. ActualizarContadores();
    4.  
    5. if ( IsFinal( streamUltimo ) )
    6. {
    7. emit Finish();
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: qtimer and signal

    I think OP meant that finished() signal is fired more than once after the "final" processing.
    You can use boolean variable the control it:
    Qt Code:
    1. Stream::Stream(QWidget *parent) :
    2. QObject(parent)
    3. {
    4.  
    5. Timer = new QTimer();
    6. connect(Timer, SIGNAL(timeout()), this, SLOT(Update()));
    7. Timer->start(30);
    8. this->isFinished = false; // declared as bool member
    9. }
    10.  
    11. void Stream::Update(){
    12. if( this->isFinished )
    13. return;
    14.  
    15. ActualizarContadores();
    16.  
    17. if ( IsFinal( streamUltimo ) )
    18. {
    19. this->isFinished = true;
    20. if( Timer->isActive() )
    21. {
    22. Timer->stop();
    23. emit Finish();
    24. }
    25. }
    26.  
    27. }
    To copy to clipboard, switch view to plain text mode 
    Since everything happens in one thread, you can be sure that Finish() will be emitted once in this case.

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,315
    Thanks
    314
    Thanked 870 Times in 857 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qtimer and signal

    I think OP meant that finished() signal is fired more than once after the "final" processing.
    Right, and I think Spitfire was correct in ascertaining why - the timer fires again before the first processing finishes, so the slot is entered again. In your code, I don't think the Boolean flag adds anything that stopping the timer doesn't already do, except to prevent the other functions from being called more than once. Once the timer has been stopped first time through the slot, the Finished signal won't be fired again because isActive() will be false. Your flag actually will prevent the GUI from being updated ("ActualizarContadores").

    I assumed that the OP wanted to simply wait 30 ms before the slot gets called. If in fact he wanted to continuously update the GUI until IsFinal() returns true, then Spitfire's code will do this and also ensures that the Finished() signal get emitted exactly once unless something elsewhere restarts the timer.

    It's hard to know what the OP's actual intent is, with just fragments of code.

Similar Threads

  1. Replies: 2
    Last Post: 3rd May 2011, 20:22
  2. Replies: 3
    Last Post: 2nd April 2011, 13:13
  3. Replies: 2
    Last Post: 9th September 2009, 00:26
  4. signal mapping on pushbutton signal clicked
    By wagmare in forum Qt Programming
    Replies: 2
    Last Post: 17th March 2009, 07:54
  5. QTimer
    By Ahmad in forum Qt Programming
    Replies: 1
    Last Post: 22nd October 2007, 18:26

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.