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

View File

@ -2865,3 +2865,13 @@
\sa QApplication::setNavigationMode() \sa QApplication::setNavigationMode()
\sa QApplication::navigationMode() \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 "qbasictimer.h"
#include "qcoreapplication.h"
#include "qabstracteventdispatcher.h" #include "qabstracteventdispatcher.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -120,6 +119,24 @@ void QBasicTimer::start(int msec, QObject *obj)
id = obj->startTimer(msec); 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. Stops the timer.

View File

@ -43,6 +43,7 @@
#define QBASICTIMER_H #define QBASICTIMER_H
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#include <QtCore/qnamespace.h>
QT_BEGIN_HEADER QT_BEGIN_HEADER
@ -63,6 +64,7 @@ public:
inline int timerId() const { return id; } inline int timerId() const { return id; }
void start(int msec, QObject *obj); void start(int msec, QObject *obj);
void start(int msec, Qt::TimerType timerType, QObject *obj);
void stop(); void stop();
}; };
Q_DECLARE_TYPEINFO(QBasicTimer, Q_MOVABLE_TYPE); 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 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 8
Note that QTimer's accuracy depends on the underlying operating Note that QTimer's accuracy depends on the underlying operating system and
system and hardware. Most platforms support an accuracy of 20 hardware. The \a timerType argument allows you to customize the accuracy of
milliseconds; some provide more. If Qt is unable to deliver the the timer. See Qt::TimerType for information on the different timer types.
requested number of timer events, it will silently discard some. 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 The QTimer class provides a high-level programming interface with
single-shot timers and timer signals instead of events. There is 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() \sa timerEvent(), killTimer(), QTimer::singleShot()
*/ */
int QObject::startTimer(int interval) int QObject::startTimer(int interval, Qt::TimerType timerType)
{ {
Q_D(QObject); Q_D(QObject);

View File

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

View File

@ -134,7 +134,6 @@ QT_BEGIN_NAMESPACE
{Analog Clock Example}, {Wiggly Example} {Analog Clock Example}, {Wiggly Example}
*/ */
static const int INV_TIMER = -1; // invalid timer id 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) 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 if (id != INV_TIMER) // stop running timer
stop(); stop();
nulltimer = (!inter && single); nulltimer = (!inter && single);
id = QObject::startTimer(inter); id = QObject::startTimer(inter, Qt::TimerType(type));
} }
/*! /*!
@ -257,18 +256,18 @@ class QSingleShotTimer : public QObject
int timerId; int timerId;
public: public:
~QSingleShotTimer(); ~QSingleShotTimer();
QSingleShotTimer(int msec, QObject *r, const char * m); QSingleShotTimer(int msec, Qt::TimerType timerType, QObject *r, const char * m);
Q_SIGNALS: Q_SIGNALS:
void timeout(); void timeout();
protected: protected:
void timerEvent(QTimerEvent *); 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()) : QObject(QAbstractEventDispatcher::instance())
{ {
connect(this, SIGNAL(timeout()), receiver, member); connect(this, SIGNAL(timeout()), receiver, member);
timerId = startTimer(msec); timerId = startTimer(msec, timerType);
} }
QSingleShotTimer::~QSingleShotTimer() QSingleShotTimer::~QSingleShotTimer()
@ -317,6 +316,25 @@ QT_END_INCLUDE_NAMESPACE
*/ */
void QTimer::singleShot(int msec, QObject *receiver, const char *member) 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 (receiver && member) {
if (msec == 0) { if (msec == 0) {
@ -330,7 +348,7 @@ void QTimer::singleShot(int msec, QObject *receiver, const char *member)
QMetaObject::invokeMethod(receiver, methodName.constData(), Qt::QueuedConnection); QMetaObject::invokeMethod(receiver, methodName.constData(), Qt::QueuedConnection);
return; 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; inter = msec;
if (id != INV_TIMER) { // create new timer if (id != INV_TIMER) { // create new timer
QObject::killTimer(id); // restart 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 QT_END_NAMESPACE

View File

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