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. Proper way to code a stopwatch

Proper way to code a stopwatch

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 7.4k 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.
  • C Offline
    C Offline
    cpper
    wrote on 29 Jan 2017, 15:33 last edited by
    #1

    I'm trying to make a stopwatch for an app I'm currently working at. I've managed to do it by using a QTimer and QTime. The step/refresh rate is 10ms. I did it by connecting a QTimer's timeout signal to a lambda slot that updates the QTime object.

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow),
        time(new QTime(0,0)),
        timer(new QTimer())
    {
        ui->setupUi(this);
    
        timer->start(10);
        connect(timer,&QTimer::timeout,[this](){
            *time=time->addMSecs(10);
            ui->label->setText(time->toString("mm:ss:zzz"));
        });
    
    }
    

    The code works well apparently but I'm wondering if there's a smarter and maybe more efficient way of doing it.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on 29 Jan 2017, 16:34 last edited by Chris Kawa
      #2

      That doesn't look correct at all. By default QTimer is Qt::CoarseTimer, which means it won't emit the signal at exactly 10ms, just somewhere near. A second problem is that signal delivery can stall sometimes. So adding 10ms in the slot is not a good way to do it as it might be actually 11 or more that passed and after some seconds the error will sum up to noticeable sizes.

      The correct way to do it is to measure time at the start and then at the intervals check how much time has passed from that starting point. This way you won't accumulate any error.
      There's a QElapsedTimer class exactly for that purpose. You start the timer and then, in your slot, call elapsed() to get the number of milliseconds that passed since the start.

      1 Reply Last reply
      4
      • C Offline
        C Offline
        cpper
        wrote on 29 Jan 2017, 17:14 last edited by
        #3

        Thanks Chris. Is there a function to convert the msecs to QTime, or a formatted string ? Or should I better do the divisions myself ?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 29 Jan 2017, 17:30 last edited by SGaist
          #4

          Hi,

          Are-you thinking about something like fromMSecsSinceStartOfDay ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          2
          • C Offline
            C Offline
            cpper
            wrote on 29 Jan 2017, 20:59 last edited by
            #5

            Yes SGaist, that's what I was looking for.
            I wrote the timer using QElapsedTimer but have now to figure out how to implement a pause->resume command. I'm thinking of putting the so far elapsed time into a variable(toPause) when clicking pause, and when clicking resume to restart the elapsedTimer. In the label I'd print toPause+elapsedTimer.elapsed(). I think it'll work but I'm not sure how accurate it'll be.

            C 1 Reply Last reply 29 Jan 2017, 21:09
            0
            • C cpper
              29 Jan 2017, 20:59

              Yes SGaist, that's what I was looking for.
              I wrote the timer using QElapsedTimer but have now to figure out how to implement a pause->resume command. I'm thinking of putting the so far elapsed time into a variable(toPause) when clicking pause, and when clicking resume to restart the elapsedTimer. In the label I'd print toPause+elapsedTimer.elapsed(). I think it'll work but I'm not sure how accurate it'll be.

              C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 29 Jan 2017, 21:09 last edited by
              #6

              @cpper said in Proper way to code a stopwatch:

              I think it'll work but I'm not sure how accurate it'll be

              That should be fine. "Clicking" is not a very accurate operation in itself and users of stopwatches don't usually press pause/resume thousands of times in one measure. I'd say it's gonna be as accurate as the user can be.

              1 Reply Last reply
              1
              • C Offline
                C Offline
                cpper
                wrote on 29 Jan 2017, 21:12 last edited by cpper
                #7

                All clear now. Thanks guys :)
                alt text

                1 Reply Last reply
                1

                1/7

                29 Jan 2017, 15:33

                • Login

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