summaryrefslogtreecommitdiffstats
path: root/src/corelib/doc/src/timers.qdoc
blob: dc205a47b993b30e64230996f1dd1e72a5416996 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \page timers.html
    \title Timers
    \brief How to use Qt timers in your application.

    \ingroup how-to

    QObject, the base class of all Qt objects, provides the basic
    timer support in Qt. With QObject::startTimer(), you start a
    timer with an interval in milliseconds as argument. The function
    returns a unique integral timer ID. The timer will then fire at
    regular intervals until you explicitly call QObject::killTimer()
    with that timer ID.

    For this mechanism to work, the application must run in an event
    loop. You cat start an event loop with QApplication::exec(). When a
    timer fires, the application sends a QTimerEvent, and the flow of
    control leaves the event loop until the timer event is processed.
    This implies that a timer cannot fire while your application is
    busy doing something else. In other words: the accuracy of timers
    depends on the granularity of your application.

    In multithreaded applications, you can use the timer mechanism in
    any thread that has an event loop. To start an event loop from a
    non-GUI thread, use QThread::exec(). Qt uses the object's
    \l{QObject::thread()}{thread affinity} to determine which thread
    will deliver the QTimerEvent. Because of this, you must start and
    stop all timers in the object's thread; it is not possible to
    start timers for objects in another thread.

    The main API for the timer functionality was \l QTimer. QTimer stores
    the interval in a signed integer, which limits the maximum interval it
    supports to the number of milliseconds that can fit in a signed integer
    (in practice, this is a period of around 24 days).

    Qt 6.8 introduced the \l QChronoTimer class to replace QTimer. QChronoTimer
    stores the interval as \c std::chrono::nanoseconds, which means that
    the maximum interval it supports is around 292 years. This mitigates
    the chances of integer overflow that QTimer had if the interval was more
    than \c{std::numeric_limits<int>::max()}.

    The accuracy of the timers depends on the underlying operating system.
    Windows 2000 has 15ms accuracy; other systems that we have tested can
    handle 1ms intervals.

    QChronoTimer provides regular timers that emit a signal when the timer
    fires, and inherits from QObject so that it fits well into the ownership
    structure of most Qt programs. The normal way of using it is like this:

    \snippet timers/timers.cpp timer-interval-in-ctor
    \snippet timers/timers.cpp timer-setinterval

    The QChronoTimer object is made into a child of the \c this object so
    that, when \c this is destroyed, the timer is destroyed too. Next, the
    \l{QChronoTimer::}{timeout()} signal is connected to the slot that will
    do the work, the timer interval can be either passed to the constructor,
    or set later on with setInterval().

    QChronoTimer also provides static functions for single-shot timers.
    For example:

    \snippet timers/timers.cpp qchronotimer-singleshot

    200ms after this line of code is executed, the \c updateCaption() slot
    will be called.

    For QChronoTimer to work, you must have an event loop in your application;
    that is, you must call QCoreApplication::exec() somewhere. Timer events
    will be delivered only while the event loop is running.

    In multithreaded applications, you can use QChronoTimer in any thread
    that has an event loop. To start an event loop from a non-GUI thread, use
    QThread::exec(). Qt uses the timer's \l{QObject::thread()}{thread affinity}
    to determine which thread will emit the \l{QChronoTimer::}{timeout()}
    signal. Because of this, you must start and stop the timer in its thread;
    it is not possible to start a timer from another thread.

    The \l{widgets/analogclock}{Analog Clock} example shows how to
    use QChronoTimer to redraw a widget at regular intervals. From
    \c{AnalogClock}'s implementation:

    \snippet timers/analogclock.cpp analogclock-qchronotimer

    Every second, QChronoTimer will call the QWidget::update() slot to
    refresh the clock's display.

    If you already have a QObject subclass and want an easy
    optimization, you can use QBasicTimer instead of QTimer. With
    QBasicTimer, you must reimplement
    \l{QObject::timerEvent()}{timerEvent()} in your QObject subclass
    and handle the timeout there.
*/