Add Qt::TimerType and the QTimer::timerType property

The timer type will control the accuracy of the timer. By default, all
timers are CoarseTimers, which allows for +/- 5% interval adjustment.
PreciseTimers will not have any interval adjustments, VeryCoarseTimers
will have intervals adjusted to full second resolution.

Use QTimer::setTimerType() or the QTimer::singleShot() overload to
specify the type.

QObject::startTimer() now takes a Qt::TimerType argument which defaults
to Qt::CoarseTimer. QBasicTimer::startTimer() gets an overload that
takes a Qt::TimerType argument. The argument is unused for now, since
the QAbstractEventDispatcher interface needs to change (done in a
separate commit).

Author: Thiago Macieira <thiago.macieira@nokia.com>
Change-Id: I3100da5aa1fe17ec30b8644897d0fe6ec4a07f52
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Bradley T. Hughes 2011-12-21 11:32:43 +01:00 committed by Qt by Nokia
parent 05ca21411e
commit ef60ed1c9d
8 changed files with 87 additions and 15 deletions

View File

@ -97,6 +97,7 @@ Qt {
Q_ENUMS(GestureType)
#endif
Q_ENUMS(CursorMoveStyle)
Q_ENUMS(TimerType)
#endif // defined(Q_MOC_RUN)
#if defined(Q_MOC_RUN)
@ -1527,6 +1528,12 @@ public:
LogicalMoveStyle,
VisualMoveStyle
};
enum TimerType {
PreciseTimer,
CoarseTimer,
VeryCoarseTimer
};
}
#ifdef Q_MOC_RUN
;

View File

@ -2865,3 +2865,13 @@
\sa QApplication::setNavigationMode()
\sa QApplication::navigationMode()
*/
/*!
\enum Qt::TimerType
The timer type indicates how accurate a timer can be.
\value PreciseTimer Precise timers try to keep millisecond accuracy
\value CoarseTimer Coarse timers try to keep accuracy within 5% of the desired interval
\value VeryCoarseTimer Very coarse timers only keep full second accuracy
*/

View File

@ -40,7 +40,6 @@
****************************************************************************/
#include "qbasictimer.h"
#include "qcoreapplication.h"
#include "qabstracteventdispatcher.h"
QT_BEGIN_NAMESPACE
@ -120,6 +119,24 @@ void QBasicTimer::start(int msec, QObject *obj)
id = obj->startTimer(msec);
}
/*!
\overload
Starts (or restarts) the timer with a \a msec milliseconds timeout and the
given \a timerType. See Qt::TimerType for information on the different
timer types.
The given \a object will receive timer events.
\sa stop() isActive() QObject::timerEvent() Qt::TimerType
*/
void QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
{
stop();
if (obj)
id = obj->startTimer(msec, timerType);
}
/*!
Stops the timer.

View File

@ -43,6 +43,7 @@
#define QBASICTIMER_H
#include <QtCore/qglobal.h>
#include <QtCore/qnamespace.h>
QT_BEGIN_HEADER
@ -63,6 +64,7 @@ public:
inline int timerId() const { return id; }
void start(int msec, QObject *obj);
void start(int msec, Qt::TimerType timerType, QObject *obj);
void stop();
};
Q_DECLARE_TYPEINFO(QBasicTimer, Q_MOVABLE_TYPE);

View File

@ -1358,10 +1358,12 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 8
Note that QTimer's accuracy depends on the underlying operating
system and hardware. 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.
Note that QTimer's accuracy 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
@ -1371,7 +1373,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
\sa timerEvent(), killTimer(), QTimer::singleShot()
*/
int QObject::startTimer(int interval)
int QObject::startTimer(int interval, Qt::TimerType timerType)
{
Q_D(QObject);

View File

@ -150,7 +150,7 @@ public:
QThread *thread() const;
void moveToThread(QThread *thread);
int startTimer(int interval);
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
void killTimer(int id);
template<typename T>

View File

@ -134,7 +134,6 @@ QT_BEGIN_NAMESPACE
{Analog Clock Example}, {Wiggly Example}
*/
static const int INV_TIMER = -1; // invalid timer id
/*!
@ -142,7 +141,7 @@ static const int INV_TIMER = -1; // invalid timer id
*/
QTimer::QTimer(QObject *parent)
: QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0)
: QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0), type(Qt::CoarseTimer)
{
}
@ -203,7 +202,7 @@ void QTimer::start()
if (id != INV_TIMER) // stop running timer
stop();
nulltimer = (!inter && single);
id = QObject::startTimer(inter);
id = QObject::startTimer(inter, Qt::TimerType(type));
}
/*!
@ -257,18 +256,18 @@ class QSingleShotTimer : public QObject
int timerId;
public:
~QSingleShotTimer();
QSingleShotTimer(int msec, QObject *r, const char * m);
QSingleShotTimer(int msec, Qt::TimerType timerType, QObject *r, const char * m);
Q_SIGNALS:
void timeout();
protected:
void timerEvent(QTimerEvent *);
};
QSingleShotTimer::QSingleShotTimer(int msec, QObject *receiver, const char *member)
QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, QObject *receiver, const char *member)
: QObject(QAbstractEventDispatcher::instance())
{
connect(this, SIGNAL(timeout()), receiver, member);
timerId = startTimer(msec);
timerId = startTimer(msec, timerType);
}
QSingleShotTimer::~QSingleShotTimer()
@ -317,6 +316,25 @@ QT_END_INCLUDE_NAMESPACE
*/
void QTimer::singleShot(int msec, QObject *receiver, const char *member)
{
singleShot(msec, Qt::CoarseTimer, receiver, member);
}
/*! \overload
\reentrant
This static function calls a slot after a given time interval.
It is very convenient to use this function because you do not need
to bother with a \link QObject::timerEvent() timerEvent\endlink or
create a local QTimer object.
The \a receiver is the receiving object and the \a member is the slot. The
time interval is \a msec milliseconds. The \a timerType affects the
accuracy of the timer.
\sa start()
*/
void QTimer::singleShot(int msec, Qt::TimerType timerType, QObject *receiver, const char *member)
{
if (receiver && member) {
if (msec == 0) {
@ -330,7 +348,7 @@ void QTimer::singleShot(int msec, QObject *receiver, const char *member)
QMetaObject::invokeMethod(receiver, methodName.constData(), Qt::QueuedConnection);
return;
}
(void) new QSingleShotTimer(msec, receiver, member);
(void) new QSingleShotTimer(msec, timerType, receiver, member);
}
}
@ -361,8 +379,17 @@ void QTimer::setInterval(int msec)
inter = msec;
if (id != INV_TIMER) { // create new timer
QObject::killTimer(id); // restart timer
id = QObject::startTimer(msec);
id = QObject::startTimer(msec, Qt::TimerType(type));
}
}
/*!
\property QTimer::timerType
\brief controls the accuracy of the timer
The default value for this property is \c Qt::CoarseTimer.
\sa Qt::TimerType
*/
QT_END_NAMESPACE

View File

@ -58,6 +58,7 @@ class Q_CORE_EXPORT QTimer : public QObject
Q_OBJECT
Q_PROPERTY(bool singleShot READ isSingleShot WRITE setSingleShot)
Q_PROPERTY(int interval READ interval WRITE setInterval)
Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType)
Q_PROPERTY(bool active READ isActive)
public:
explicit QTimer(QObject *parent = 0);
@ -69,10 +70,14 @@ public:
void setInterval(int msec);
int interval() const { return inter; }
void setTimerType(Qt::TimerType type) { this->type = type; }
Qt::TimerType timerType() const { return Qt::TimerType(type); }
inline void setSingleShot(bool singleShot);
inline bool isSingleShot() const { return single; }
static void singleShot(int msec, QObject *receiver, const char *member);
static void singleShot(int msec, Qt::TimerType timerType, QObject *receiver, const char *member);
public Q_SLOTS:
void start(int msec);
@ -95,6 +100,8 @@ private:
int id, inter, del;
uint single : 1;
uint nulltimer : 1;
uint type : 2;
// reserved : 28
};
inline void QTimer::setSingleShot(bool asingleShot) { single = asingleShot; }