20. Timers

In programming, timers are used to measure time intervals and trigger actions or events after a speecified delay (single-shot) or at regular intervals. They enable task scheduling, such as updating GUI elements, or polling resources, without blocking the main execution flow.1

In Qt, timers are integrated with the application’s event loop. They allow non-blocking time-based operations, ensuring responsive applications, ensuring responsive GUI applications. Qt provides several timer facilites:

  • QObject.startTimer(): A low-level method on any QObject to start a timer with a millisecond interval.

  • QBasicTimer: A lightweight wrapper around a timer Id from startTimer()

  • QTimer: A high-level QObject subclass with millisecond precision (up to 24 days range) which emits a timeout() signal.

  • QChronoTimer: A drop-in replacement for QTimer but with nanosecond precision and larger ranges (up to 292 years).

The following two timer classes do not integrate with the Qt event loop:

  • QElapsedTimer: A stopwatch for measuring elapsed time.

  • QDeadlineTimer: Represents a deadline for timeouts in blocking functions.

The one you will be using the most of the time is QTimer - here are its most important methods:

Here’s a table of QTimer’s most important methods:

Method Description
start(int msec) Starts or restarts the timer with a timeout of msec milliseconds
start() Starts or restarts the timer with the timeout specified in setInterval()
stop() Stops the timer
setInterval(int msec) Sets the timeout interval in milliseconds
interval() Returns the current interval in milliseconds
isActive() Returns true if the timer is running, false otherwise
setSingleShot(bool) Sets whether the timer fires only once (true) or repeatedly (false)
isSingleShot() Returns true if the timer is single-shot
timerId() Returns the timer’s ID, or -1 if the timer is not running
remainingTime() Returns the remaining time in milliseconds before the timer times out
setTimerType(Qt::TimerType) Sets the timer’s precision (Precise, Coarse, or VeryCoarse)
timerType() Returns the timer’s type
timeout Signal emitted when the timer times out
singleShot(int msec, receiver, slot) Static method that creates a single-shot timer that calls a slot after msec milliseconds

20.1 Single-Shot

Qt’s single-shot timer is a feature of the QTimer class that allows developers to schedule a one-time event to occur after a specified delay,without the need for repeated intervals. It can be useful for tasks like delaying UI updates, handling asynchronous operations, or implementing timeouts in applications.

An icon of a clipboard-list1

You need to updata a label’s text one second after a button is clicked.

To do this:

  1. Create QPushButton and QLabel instances, add them to the window layout, and connect the button’s clicked signal to a slot.

  2. In the slot, call QTimer.singleShot(), passing a 1000ms delay interval and the on_single_shot() method to execute after the delay.

  3. In on_single_shot(), get the current time and display it in the label. This executes with a one-second delay while keeping the GUI responsive.

As singleSHot() is a class (static) method, you don’t create an instance of the QTimer class.

20.2 Starting and Stopping a Timer

Calling a timer’s start() method begins firing timeout() signals at specified intervals. Stopping a timer with stop() halts its operation, preventing further timeouts until it is restarted.

An icon of a clipboard-list1

You are given the task of creating a simple application that counts elapsed seconds, allowing the user to start and stop the tracking as needed.

To do this:

  1. Create a Start timer and a Stop timer QPushButtons along with a QLabel that displays the current number of elapsed seconds. Keep the count in an instance field named counter initialized to 0.

  2. Create a QTimer object and set its interval to 1000 milliseconds.

  3. When the Start timer button is clicked:

    • Disable the Start button and enable the Stop button,
    • Start the timer.

    When the Stop timer button is clicked:

    • Enable the Start button and disable the Stop button,
    • Stop the timer.
  4. Each time the timer’s timeout signal is emitted, increment counter by one and update the label to show the new value.

20.3 Adjusting a Timer Interval

An icon of a clipboard-list1

You need a timer that remains active through your application’s runtime, while allowing the user to adjust its interval without restarting the countdown.

  1. Create the spinbox and timer. In the main window’s __init__(), create a QSpinBox with an initial value of 1000ms, a range of 200-2000 ms, and a step of 100ms. COnnect its valueChanged() signal to a slot for handling value changes. Then, create a QTimer, connect its timeout() signal to a slot, and start it with the initial interval.

  2. When the user changes the spinbox value, store that value in the pending_interval instance variable.

  3. On the timer’s timeout() signal, check if pending_interval is set. If it is, adjust the timer interval and reset pending_interval to None. Also perform your application timer-related tasks (in this case, update a label).

The intermediate pending_interval variable is necessary to avoid restarting the timer’s current countdown cycle when the spinbox value changes. Calling setInterval() directly on a running QTimer stops and restarts it, resetting the countdown to the new interval from that moment, which could delay or advance the next timeout() signal. By using pending_interval, we defer the change until the start of the on_timeout() slot - after the current interval has completed - ensuring the new interval only applies to future cycles without interrupting the ongoing one.

20.4 Countdown Timer

Countdown timers are designed to count down from a specified time interval to zero, signaling the end of a period or event. They operate by decrementing the time at regular intervals, often in seconds, and can trigger actions like notifications or program executions upon reaching zero.

An icon of a clipboard-list1

You need to implement a simple countdown in your application.

  1. Add a counter variable to your main class and set its initial value. Add a spinbox to let the user set the starting countdown value and a button to start the countdown. Also, create a QTimer and set its interval.

  2. On the Start button click, set counter value, disable the Start button and the spinbox, and start the timer.

  3. On the timer timeout(), decrement counter, update the label text, and if counter reaches zero, stop the timer and re-anable the button and the spinbox.

This ensures the countdown runs uninterrupted by disabling controls during operation, providing a basic countdown mechanism.

20.5 Stopwatch

The previous example showed how to decrease a counter value at regular intervals, stopping the timer when the counter reaches zero. Conversely, you can also use a timer to increase a value periodically.

An icon of a clipboard-list1

Your task is to create a simple stopwatch application with one-hundredth of a second (100ms) resolution and ‘Start’, ‘Pause’ and ‘Reset’ functionality.

  1. Add an elapsed_time instance variable to the main window. This is a QTime object initialized to zero hours, minutes, seconds and milliseconds. QTime is convenient here because it provides addMSecs() for easy time increments.

  2. Create the buttons. When the aplication starts, the ‘Start’ button is enabled, the ‘Pause’ button is disabled and the ‘Reset’ button is always enabled (allowing reset at any time).

    • Clicking ‘Start’ disables it, enables ‘Pause’ and starts the timer.
    • Clicking ‘Pause’ disables it, enables ‘Start’ and stops the timer.
  3. Create a QTimer, set its interval to 100 milliseconds, and connect its timeout() signal to a slot.

  4. Update the time. In the on_timeout() slot, add the 100 ms to elapsed_time using addMSecs(), then update a label to display the current time in the format mm:ss.z (minutes:seconds.tenths).


  1. If you don’t implement __init__() in your class at all, the parent class gets initalized automatically.↩︎