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"
// QTimer
//! [0]
AnalogClock::AnalogClock(QWidget *parent)
//! [0] //! [2]
@ -25,6 +26,21 @@ AnalogClock::AnalogClock(QWidget *parent)
}
//! [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 *)
{
static const QPoint hourHand[3] = {

View File

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

View File

@ -11,12 +11,12 @@
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 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()
with the timer ID.
with that timer ID.
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
control leaves the event loop until the timer event is processed.
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
start timers for objects in another thread.
The upper limit for the interval value is determined by the number
of milliseconds that can be specified in a signed integer
(in practice, this is a period of just over 24 days). The accuracy
depends on the underlying operating system. Windows 2000 has 15
millisecond accuracy; other systems that we have tested can handle
1 millisecond intervals.
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).
The main API for the timer functionality is QTimer. That class
provides regular timers that emit a signal when the timer fires, and
inherits QObject so that it fits well into the ownership structure
of most Qt programs. The normal way of using it is like this:
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()}.
\snippet timers/timers.cpp 0
\snippet timers/timers.cpp 1
\snippet timers/timers.cpp 2
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.
The QTimer object is made into a child of \c this object so that,
when \c this object is deleted, the timer is deleted too.
Next, its \l{QTimer::}{timeout()} signal is connected to the slot
that will do the work, it is started with a value of 1000
milliseconds, indicating that it will time out every second.
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:
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:
\snippet timers/timers.cpp 3
\snippet timers/timers.cpp qchronotimer-singleshot
200 milliseconds (0.2 seconds) after this line of code is
executed, the \c updateCaption() slot will be called.
200ms after this line of code is executed, the \c updateCaption() slot
will be called.
For QTimer 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.
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 QTimer 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{QTimer::}{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.
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
QTimer to redraw a widget at regular intervals. From \c{AnalogClock}'s
implementation:
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 0
\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
\snippet timers/analogclock.cpp analogclock-qchronotimer
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.
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
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.
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
*/

View File

@ -1364,7 +1364,8 @@ bool QCoreApplication::closingDown()
\threadsafe
\sa exec(), QTimer, QEventLoop::processEvents(), sendPostedEvents()
\sa exec(), QTimer, QChronoTimer, QEventLoop::processEvents(),
sendPostedEvents()
*/
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
{
@ -1413,7 +1414,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
\threadsafe
\sa exec(), QTimer, QEventLoop::processEvents()
\sa exec(), QTimer, QChronoTimer, QEventLoop::processEvents()
*/
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
dispatches these to the application widgets.
To make your application perform idle processing (by executing a
special function whenever there are no pending events), use a
QTimer with 0 timeout. More advanced idle processing schemes can
be achieved using processEvents().
To make your application perform idle processing (by executing a special
function whenever there are no pending events), use a QChronoTimer
with 0ns timeout. More advanced idle processing schemes can be achieved
using processEvents().
We recommend that you connect clean-up code to the
\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
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.
The event handler QObject::timerEvent() receives timer events.
\sa QTimer, QObject::timerEvent(), QObject::startTimer(),
\sa QChronoTimer, QObject::timerEvent(), QObject::startTimer(),
QObject::killTimer()
*/

View File

@ -84,11 +84,12 @@ static qint64 add_saturate(qint64 t1, Duration1 dur, Durations... extra)
\section1 Timer types
Like QTimer, QDeadlineTimer can select among different levels of coarseness
on the timers. You can select precise timing by passing Qt::PreciseTimer to
the functions that set of change the timer, or you can select coarse timing
by passing Qt::CoarseTimer. Qt::VeryCoarseTimer is currently interpreted
the same way as Qt::CoarseTimer.
Like QTimer and QChronoTimer, QDeadlineTimer can select among
different levels of coarseness on the timers. You can select
precise timing by passing Qt::PreciseTimer to the functions that
set of change the timer, or you can select coarse timing by passing
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
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
\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
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
use their own local event loop.
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. More sophisticated idle processing schemes
can be achieved using processEvents().
To make your application perform idle processing (i.e. executing a special
function whenever there are no pending events), use a QChronoTimer with
0ns timeout. More sophisticated idle processing schemes can be achieved
using processEvents().
\sa QCoreApplication::quit(), exit(), processEvents()
*/

View File

@ -810,7 +810,7 @@ QMetaCallEvent* QMetaCallEvent::create_impl(QtPrivate::SlotObjUniquePtr slotObj,
to catch child events.
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
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
timer events for the object.
QTimer provides a higher-level interface to the timer
functionality, and also more general information about timers. The
timer event is passed in the \a event parameter.
QChronoTimer provides higher-level interfaces to the timer functionality,
and also more general information about timers. The timer event is passed
in the \a event parameter.
\sa startTimer(), killTimer(), event()
*/
@ -1839,7 +1839,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
startTimer(std::chrono::milliseconds{interval}, timerType);
\endcode
\sa timerEvent(), killTimer(), QTimer::singleShot()
\sa timerEvent(), killTimer(), QChronoTimer::singleShot()
*/
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
Note that QTimer's accuracy depends on the underlying operating system and
hardware. The \a timerType argument allows you to customize the accuracy of
Note that the accuracy of QChronoTimer depends on the underlying operating
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.
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
silently discard some.
The QTimer class provides a high-level programming interface with
single-shot timers and timer signals instead of events. There is
also a QBasicTimer class that is more lightweight than QTimer and
less clumsy than using timer IDs directly.
The QTimer and QChronoTimer classes provide a high-level programming
interface with single-shot timers and timer signals instead of
events. There is also a QBasicTimer class that is more lightweight than
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
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
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
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
general, since Qt is an event-driven framework. 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
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().
To make your application perform idle processing, e.g., executing a special
function whenever there are no pending events, use a QTimer with 0 timeout.
More advanced idle processing schemes can be achieved using processEvents().
To make your application perform idle processing, e.g., executing a
special function whenever there are no pending events, use a QChronoTimer
with 0ns timeout. More advanced idle processing schemes can be achieved
using processEvents().
We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your

View File

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

View File

@ -173,8 +173,9 @@
parameter describes the type of error that occurred.
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
loop. For example, use a QTimer::singleShot() with 0 as the timeout.
attempt. In that case, attempts to reconnect should be done from the
event loop. For example, use QChronoTimer::singleShot() with 0ns as
the timeout.
QAbstractSocket::SocketError is not a registered metatype, so for queued
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
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
better choice to rely on synchronization to the vertical refresh rate of the
display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a

View File

@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
\endlist
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.
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
place in the background, where the user is able to interact with the
application. Such operations are typically based on QTimer (or
QObject::timerEvent()) or QSocketNotifier; or performed
in a separate thread. A QProgressBar in the status bar of your main window
is often an alternative to a modeless progress dialog.
application. Such operations are typically based on a timer class,
such as QChronoTimer (or the more low-level QObject::timerEvent()) or
QSocketNotifier; or performed in a separate thread. A QProgressBar in
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
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.
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.
More advanced idle processing schemes can be achieved using processEvents().
function whenever there are no pending events, use a QChronoTimer with 0ns
timeout. More advanced idle processing schemes can be achieved using
processEvents().
We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your