Mention QChronoTimer in API docs

Change-Id: Iaf9fb31994f1580b2051dbd0b1b8eef2a218aa39
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2023-07-13 03:01:46 +03:00
parent 4bc0834bc1
commit c610cfe328
20 changed files with 128 additions and 98 deletions

View File

@ -5,6 +5,7 @@
#include "analogclock.h" #include "analogclock.h"
// QTimer
//! [0] //! [0]
AnalogClock::AnalogClock(QWidget *parent) AnalogClock::AnalogClock(QWidget *parent)
//! [0] //! [2] //! [0] //! [2]
@ -25,6 +26,21 @@ AnalogClock::AnalogClock(QWidget *parent)
} }
//! [7] //! [7]
//! [analogclock-qchronotimer]
AnalogClock::AnalogClock(QWidget *parent)
: QWidget(parent)
{
auto *timer = new QChronoTimer(1s, this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update));
timer->start();
...
...
setWindowTitle(tr("Analog Clock"));
resize(200, 200);
}
//! [analogclock-qchronotimer]
void AnalogClock::paintEvent(QPaintEvent *) void AnalogClock::paintEvent(QPaintEvent *)
{ {
static const QPoint hourHand[3] = { static const QPoint hourHand[3] = {

View File

@ -46,7 +46,7 @@ class MyWidget : QObject
{ {
//! [qchronotimer-singleshot] //! [qchronotimer-singleshot]
MyWidget widget; MyWidget widget;
QChronoTimer::singleShot(100ms, &widget, &MyWidget::processOneThing); QChronoTimer::singleShot(200ms, &widget, &MyWidget::updateCaption);
//! [qchronotimer-singleshot] //! [qchronotimer-singleshot]
//! [zero-timer] //! [zero-timer]

View File

@ -11,12 +11,12 @@
QObject, the base class of all Qt objects, provides the basic QObject, the base class of all Qt objects, provides the basic
timer support in Qt. With QObject::startTimer(), you start a timer support in Qt. With QObject::startTimer(), you start a
timer with an interval in milliseconds as argument. The function timer with an interval in milliseconds as argument. The function
returns a unique integer timer ID. The timer will now fire at returns a unique integral timer ID. The timer will then fire at
regular intervals until you explicitly call QObject::killTimer() regular intervals until you explicitly call QObject::killTimer()
with the timer ID. with that timer ID.
For this mechanism to work, the application must run in an event For this mechanism to work, the application must run in an event
loop. You start an event loop with QApplication::exec(). When a loop. You cat start an event loop with QApplication::exec(). When a
timer fires, the application sends a QTimerEvent, and the flow of timer fires, the application sends a QTimerEvent, and the flow of
control leaves the event loop until the timer event is processed. control leaves the event loop until the timer event is processed.
This implies that a timer cannot fire while your application is This implies that a timer cannot fire while your application is
@ -31,63 +31,60 @@
stop all timers in the object's thread; it is not possible to stop all timers in the object's thread; it is not possible to
start timers for objects in another thread. start timers for objects in another thread.
The upper limit for the interval value is determined by the number The main API for the timer functionality was \l QTimer. QTimer stores
of milliseconds that can be specified in a signed integer the interval in a signed integer, which limits the maximum interval it
(in practice, this is a period of just over 24 days). The accuracy supports to the number of milliseconds that can fit in a signed integer
depends on the underlying operating system. Windows 2000 has 15 (in practice, this is a period of around 24 days).
millisecond accuracy; other systems that we have tested can handle
1 millisecond intervals.
The main API for the timer functionality is QTimer. That class Qt 6.8 introduced the \l QChronoTimer class to replace QTimer. QChronoTimer
provides regular timers that emit a signal when the timer fires, and stores the interval as \c std::chrono::nanoseconds, which means that
inherits QObject so that it fits well into the ownership structure the maximum interval it supports is around 292 years. This mitigates
of most Qt programs. The normal way of using it is like this: the chances of integer overflow that QTimer had if the interval was more
than \c{std::numeric_limits<int>::max()}.
\snippet timers/timers.cpp 0 The accuracy of the timers depends on the underlying operating system.
\snippet timers/timers.cpp 1 Windows 2000 has 15ms accuracy; other systems that we have tested can
\snippet timers/timers.cpp 2 handle 1ms intervals.
The QTimer object is made into a child of \c this object so that, QChronoTimer provides regular timers that emit a signal when the timer
when \c this object is deleted, the timer is deleted too. fires, and inherits from QObject so that it fits well into the ownership
Next, its \l{QTimer::}{timeout()} signal is connected to the slot structure of most Qt programs. The normal way of using it is like this:
that will do the work, it is started with a value of 1000
milliseconds, indicating that it will time out every second.
QTimer also provides a static function for single-shot timers. \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: For example:
\snippet timers/timers.cpp 3 \snippet timers/timers.cpp qchronotimer-singleshot
200 milliseconds (0.2 seconds) after this line of code is 200ms after this line of code is executed, the \c updateCaption() slot
executed, the \c updateCaption() slot will be called. will be called.
For QTimer to work, you must have an event loop in your For QChronoTimer to work, you must have an event loop in your application;
application; that is, you must call QCoreApplication::exec() that is, you must call QCoreApplication::exec() somewhere. Timer events
somewhere. Timer events will be delivered only while the event will be delivered only while the event loop is running.
loop is running.
In multithreaded applications, you can use QTimer in any thread In multithreaded applications, you can use QChronoTimer in any thread
that has an event loop. To start an event loop from a non-GUI that has an event loop. To start an event loop from a non-GUI thread, use
thread, use QThread::exec(). Qt uses the timer's QThread::exec(). Qt uses the timer's \l{QObject::thread()}{thread affinity}
\l{QObject::thread()}{thread affinity} to determine which thread to determine which thread will emit the \l{QChronoTimer::}{timeout()}
will emit the \l{QTimer::}{timeout()} signal. Because of this, you signal. Because of this, you must start and stop the timer in its thread;
must start and stop the timer in its thread; it is not possible to it is not possible to start a timer from another thread.
start a timer from another thread.
The \l{widgets/analogclock}{Analog Clock} example shows how to use The \l{widgets/analogclock}{Analog Clock} example shows how to
QTimer to redraw a widget at regular intervals. From \c{AnalogClock}'s use QChronoTimer to redraw a widget at regular intervals. From
implementation: \c{AnalogClock}'s implementation:
\snippet timers/analogclock.cpp 0 \snippet timers/analogclock.cpp analogclock-qchronotimer
\snippet timers/analogclock.cpp 2
\snippet timers/analogclock.cpp 3
\snippet timers/analogclock.cpp 4
\snippet timers/analogclock.cpp 5
\snippet timers/analogclock.cpp 6
\dots
\snippet timers/analogclock.cpp 7
Every second, QTimer will call the QWidget::update() slot to Every second, QChronoTimer will call the QWidget::update() slot to
refresh the clock's display. refresh the clock's display.
If you already have a QObject subclass and want an easy If you already have a QObject subclass and want an easy

View File

@ -33,7 +33,8 @@ QT_BEGIN_NAMESPACE
can maintain a list of basic timers by holding them in container can maintain a list of basic timers by holding them in container
that supports move-only types, e.g. std::vector. that supports move-only types, e.g. std::vector.
\sa QTimer, QTimerEvent, QObject::timerEvent(), Timers, {Affine Transformations} \sa QTimer, QChronoTimer, QTimerEvent, QObject::timerEvent(),
Timers, {Affine Transformations}
*/ */

View File

@ -368,7 +368,8 @@ QBindable<Qt::TimerType> QChronoTimer::bindableTimerType()
\c SLOT() macro to get this parameter. \c SLOT() macro to get this parameter.
This function is provided as a convenience to save the need to use a This function is provided as a convenience to save the need to use a
\l{QObject::timerEvent()}{timerEvent} or create a local QTimer object. \l{QObject::timerEvent()}{timerEvent} or create a local QChronoTimer
object.
\sa start(), Qt::TimerType \sa start(), Qt::TimerType
*/ */

View File

@ -1364,7 +1364,8 @@ bool QCoreApplication::closingDown()
\threadsafe \threadsafe
\sa exec(), QTimer, QEventLoop::processEvents(), sendPostedEvents() \sa exec(), QTimer, QChronoTimer, QEventLoop::processEvents(),
sendPostedEvents()
*/ */
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
{ {
@ -1413,7 +1414,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
\threadsafe \threadsafe
\sa exec(), QTimer, QEventLoop::processEvents() \sa exec(), QTimer, QChronoTimer, QEventLoop::processEvents()
*/ */
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline) void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline)
{ {
@ -1443,10 +1444,10 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, QDead
main event loop receives events from the window system and main event loop receives events from the window system and
dispatches these to the application widgets. dispatches these to the application widgets.
To make your application perform idle processing (by executing a To make your application perform idle processing (by executing a special
special function whenever there are no pending events), use a function whenever there are no pending events), use a QChronoTimer
QTimer with 0 timeout. More advanced idle processing schemes can with 0ns timeout. More advanced idle processing schemes can be achieved
be achieved using processEvents(). using processEvents().
We recommend that you connect clean-up code to the We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in

View File

@ -519,12 +519,12 @@ int QEvent::registerEventType(int hint) noexcept
started one or more timers. Each timer has a unique identifier. A started one or more timers. Each timer has a unique identifier. A
timer is started with QObject::startTimer(). timer is started with QObject::startTimer().
The QTimer class provides a high-level programming interface that The QChronoTimer class provides a high-level programming interface that
uses signals instead of events. It also provides single-shot timers. uses signals instead of events. It also provides single-shot timers.
The event handler QObject::timerEvent() receives timer events. The event handler QObject::timerEvent() receives timer events.
\sa QTimer, QObject::timerEvent(), QObject::startTimer(), \sa QChronoTimer, QObject::timerEvent(), QObject::startTimer(),
QObject::killTimer() QObject::killTimer()
*/ */

View File

@ -84,11 +84,12 @@ static qint64 add_saturate(qint64 t1, Duration1 dur, Durations... extra)
\section1 Timer types \section1 Timer types
Like QTimer, QDeadlineTimer can select among different levels of coarseness Like QTimer and QChronoTimer, QDeadlineTimer can select among
on the timers. You can select precise timing by passing Qt::PreciseTimer to different levels of coarseness on the timers. You can select
the functions that set of change the timer, or you can select coarse timing precise timing by passing Qt::PreciseTimer to the functions that
by passing Qt::CoarseTimer. Qt::VeryCoarseTimer is currently interpreted set of change the timer, or you can select coarse timing by passing
the same way as Qt::CoarseTimer. Qt::CoarseTimer. Qt::VeryCoarseTimer is currently interpreted the same
way as Qt::CoarseTimer.
This feature is dependent on support from the operating system: if the OS This feature is dependent on support from the operating system: if the OS
does not support a coarse timer functionality, then QDeadlineTimer will does not support a coarse timer functionality, then QDeadlineTimer will
@ -120,7 +121,7 @@ static qint64 add_saturate(qint64 t1, Duration1 dur, Durations... extra)
\snippet code/src_corelib_kernel_qdeadlinetimer.cpp 2 \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 2
\sa QTime, QTimer, QDeadlineTimer, Qt::TimerType \sa QTime, QChronoTimer, QDeadlineTimer, Qt::TimerType
*/ */
/*! /*!

View File

@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE
that the clock used is the same as QElapsedTimer (see that the clock used is the same as QElapsedTimer (see
QElapsedTimer::clockType()). QElapsedTimer::clockType()).
\sa QTime, QTimer, QDeadlineTimer \sa QTime, QChronoTimer, QDeadlineTimer
*/ */
/*! /*!

View File

@ -116,10 +116,10 @@ bool QEventLoop::processEvents(ProcessEventsFlags flags)
can be used before calling exec(), because modal widgets can be used before calling exec(), because modal widgets
use their own local event loop. use their own local event loop.
To make your application perform idle processing (i.e. executing a To make your application perform idle processing (i.e. executing a special
special function whenever there are no pending events), use a function whenever there are no pending events), use a QChronoTimer with
QTimer with 0 timeout. More sophisticated idle processing schemes 0ns timeout. More sophisticated idle processing schemes can be achieved
can be achieved using processEvents(). using processEvents().
\sa QCoreApplication::quit(), exit(), processEvents() \sa QCoreApplication::quit(), exit(), processEvents()
*/ */

View File

@ -810,7 +810,7 @@ QMetaCallEvent* QMetaCallEvent::create_impl(QtPrivate::SlotObjUniquePtr slotObj,
to catch child events. to catch child events.
Last but not least, QObject provides the basic timer support in Last but not least, QObject provides the basic timer support in
Qt; see QTimer for high-level support for timers. Qt; see QChronoTimer for high-level support for timers.
Notice that the Q_OBJECT macro is mandatory for any object that Notice that the Q_OBJECT macro is mandatory for any object that
implements signals, slots or properties. You also need to run the implements signals, slots or properties. You also need to run the
@ -1488,9 +1488,9 @@ bool QObject::event(QEvent *e)
This event handler can be reimplemented in a subclass to receive This event handler can be reimplemented in a subclass to receive
timer events for the object. timer events for the object.
QTimer provides a higher-level interface to the timer QChronoTimer provides higher-level interfaces to the timer functionality,
functionality, and also more general information about timers. The and also more general information about timers. The timer event is passed
timer event is passed in the \a event parameter. in the \a event parameter.
\sa startTimer(), killTimer(), event() \sa startTimer(), killTimer(), event()
*/ */
@ -1839,7 +1839,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
startTimer(std::chrono::milliseconds{interval}, timerType); startTimer(std::chrono::milliseconds{interval}, timerType);
\endcode \endcode
\sa timerEvent(), killTimer(), QTimer::singleShot() \sa timerEvent(), killTimer(), QChronoTimer::singleShot()
*/ */
int QObject::startTimer(int interval, Qt::TimerType timerType) int QObject::startTimer(int interval, Qt::TimerType timerType)
@ -1870,19 +1870,21 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
\snippet code/src_corelib_kernel_qobject.cpp 8 \snippet code/src_corelib_kernel_qobject.cpp 8
Note that QTimer's accuracy depends on the underlying operating system and Note that the accuracy of QChronoTimer depends on the underlying operating
hardware. The \a timerType argument allows you to customize the accuracy of system and hardware.
The \a timerType argument allows you to customize the accuracy of
the timer. See Qt::TimerType for information on the different timer types. the timer. See Qt::TimerType for information on the different timer types.
Most platforms support an accuracy of 20 milliseconds; some provide more. Most platforms support an accuracy of 20 milliseconds; some provide more.
If Qt is unable to deliver the requested number of timer events, it will If Qt is unable to deliver the requested number of timer events, it will
silently discard some. silently discard some.
The QTimer class provides a high-level programming interface with The QTimer and QChronoTimer classes provide a high-level programming
single-shot timers and timer signals instead of events. There is interface with single-shot timers and timer signals instead of
also a QBasicTimer class that is more lightweight than QTimer and events. There is also a QBasicTimer class that is more lightweight than
less clumsy than using timer IDs directly. QChronoTimer but less clumsy than using timer IDs directly.
\sa timerEvent(), killTimer(), QTimer::singleShot() \sa timerEvent(), killTimer(), QChronoTimer::singleShot()
\note Starting from Qt 6.8 the type of \a interval \note Starting from Qt 6.8 the type of \a interval
is \c std::chrono::nanoseconds, prior to that it was \c is \c std::chrono::nanoseconds, prior to that it was \c

View File

@ -74,6 +74,13 @@ QT_BEGIN_NAMESPACE
more and more platforms, we expect that zero-millisecond more and more platforms, we expect that zero-millisecond
QTimer objects will gradually be replaced by \l{QThread}s. QTimer objects will gradually be replaced by \l{QThread}s.
\note Since Qt 6.7 this class is superseded by \l{QChronoTimer}.
The maximum interval QTimer supports is limited by the number of
milliseconds that would fit in an \c int (which is around 24 days);
whereas QChronoTimer stores its interval as \c std::chrono::nanoseconds
(which raises that limit to around 292 million years), that is, there is
less chance of integer overflow with QChronoTimer.
\section1 Accuracy and Timer Resolution \section1 Accuracy and Timer Resolution
The accuracy of timers depends on the underlying operating system The accuracy of timers depends on the underlying operating system

View File

@ -287,7 +287,7 @@ QThreadPrivate::~QThreadPrivate()
\note wait() and the sleep() functions should be unnecessary in \note wait() and the sleep() functions should be unnecessary in
general, since Qt is an event-driven framework. Instead of general, since Qt is an event-driven framework. Instead of
wait(), consider listening for the finished() signal. Instead of wait(), consider listening for the finished() signal. Instead of
the sleep() functions, consider using QTimer. the sleep() functions, consider using QChronoTimer.
The static functions currentThreadId() and currentThread() return The static functions currentThreadId() and currentThread() return
identifiers for the currently executing thread. The former identifiers for the currently executing thread. The former

View File

@ -1905,9 +1905,10 @@ QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function)
Generally, no user interaction can take place before calling exec(). Generally, no user interaction can take place before calling exec().
To make your application perform idle processing, e.g., executing a special To make your application perform idle processing, e.g., executing a
function whenever there are no pending events, use a QTimer with 0 timeout. special function whenever there are no pending events, use a QChronoTimer
More advanced idle processing schemes can be achieved using processEvents(). with 0ns timeout. More advanced idle processing schemes can be achieved
using processEvents().
We recommend that you connect clean-up code to the We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your

View File

@ -461,8 +461,8 @@ Qt::ScreenOrientation QScreen::orientation() const
\property QScreen::refreshRate \property QScreen::refreshRate
\brief the approximate vertical refresh rate of the screen in Hz \brief the approximate vertical refresh rate of the screen in Hz
\warning Avoid using the screen's refresh rate to drive animations \warning Avoid using the screen's refresh rate to drive animations via a
via a timer such as QTimer. Instead use QWindow::requestUpdate(). timer such as QChronoTimer. Instead use QWindow::requestUpdate().
\sa QWindow::requestUpdate() \sa QWindow::requestUpdate()
*/ */

View File

@ -173,8 +173,9 @@
parameter describes the type of error that occurred. parameter describes the type of error that occurred.
When this signal is emitted, the socket may not be ready for a reconnect When this signal is emitted, the socket may not be ready for a reconnect
attempt. In that case, attempts to reconnect should be done from the event attempt. In that case, attempts to reconnect should be done from the
loop. For example, use a QTimer::singleShot() with 0 as the timeout. event loop. For example, use QChronoTimer::singleShot() with 0ns as
the timeout.
QAbstractSocket::SocketError is not a registered metatype, so for queued QAbstractSocket::SocketError is not a registered metatype, so for queued
connections, you will have to register it with Q_DECLARE_METATYPE() and connections, you will have to register it with Q_DECLARE_METATYPE() and

View File

@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
immediately result in a call to paintGL(). Calling update() multiple times in immediately result in a call to paintGL(). Calling update() multiple times in
a row will not change the behavior in any way. a row will not change the behavior in any way.
This is a slot so it can be connected to a \l QTimer::timeout() signal to This is a slot so it can be connected to a \l QChronoTimer::timeout() signal to
perform animation. Note however that in the modern OpenGL world it is a much perform animation. Note however that in the modern OpenGL world it is a much
better choice to rely on synchronization to the vertical refresh rate of the better choice to rely on synchronization to the vertical refresh rate of the
display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a

View File

@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
\endlist \endlist
If you need to trigger a repaint from places other than paintGL() (a If you need to trigger a repaint from places other than paintGL() (a
typical example is when using \l{QTimer}{timers} to animate scenes), typical example is when using \l{QChronoTimer}{timers} to animate scenes),
you should call the widget's update() function to schedule an update. you should call the widget's update() function to schedule an update.
Your widget's OpenGL rendering context is made current when Your widget's OpenGL rendering context is made current when

View File

@ -197,10 +197,11 @@ void QProgressDialogPrivate::_q_disconnectOnClose()
A modeless progress dialog is suitable for operations that take A modeless progress dialog is suitable for operations that take
place in the background, where the user is able to interact with the place in the background, where the user is able to interact with the
application. Such operations are typically based on QTimer (or application. Such operations are typically based on a timer class,
QObject::timerEvent()) or QSocketNotifier; or performed such as QChronoTimer (or the more low-level QObject::timerEvent()) or
in a separate thread. A QProgressBar in the status bar of your main window QSocketNotifier; or performed in a separate thread. A QProgressBar in
is often an alternative to a modeless progress dialog. the status bar of your main window is often an alternative to a modeless
progress dialog.
You need to have an event loop to be running, connect the You need to have an event loop to be running, connect the
canceled() signal to a slot that stops the operation, and call \l canceled() signal to a slot that stops the operation, and call \l

View File

@ -2535,8 +2535,9 @@ int QApplication::startDragDistance()
exec(), because modal widgets call exec() to start a local event loop. exec(), because modal widgets call exec() to start a local event loop.
To make your application perform idle processing, i.e., executing a special To make your application perform idle processing, i.e., executing a special
function whenever there are no pending events, use a QTimer with 0 timeout. function whenever there are no pending events, use a QChronoTimer with 0ns
More advanced idle processing schemes can be achieved using processEvents(). timeout. More advanced idle processing schemes can be achieved using
processEvents().
We recommend that you connect clean-up code to the We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your