From ef60ed1c9dbc87d9f8401036cc254a9c45cd8ca8 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 21 Dec 2011 11:32:43 +0100 Subject: 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 Change-Id: I3100da5aa1fe17ec30b8644897d0fe6ec4a07f52 Reviewed-by: Thiago Macieira --- src/corelib/global/qnamespace.h | 7 +++++++ src/corelib/global/qnamespace.qdoc | 10 +++++++++ src/corelib/kernel/qbasictimer.cpp | 19 ++++++++++++++++- src/corelib/kernel/qbasictimer.h | 2 ++ src/corelib/kernel/qobject.cpp | 12 ++++++----- src/corelib/kernel/qobject.h | 2 +- src/corelib/kernel/qtimer.cpp | 43 +++++++++++++++++++++++++++++++------- src/corelib/kernel/qtimer.h | 7 +++++++ 8 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 4c0b9cc635..1927323ea7 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -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 ; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 4abe981b59..20ae1baa80 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -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 +*/ diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp index 8efeea6fae..d91c5a9ffe 100644 --- a/src/corelib/kernel/qbasictimer.cpp +++ b/src/corelib/kernel/qbasictimer.cpp @@ -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. diff --git a/src/corelib/kernel/qbasictimer.h b/src/corelib/kernel/qbasictimer.h index f13848cb85..ae5401e99c 100644 --- a/src/corelib/kernel/qbasictimer.h +++ b/src/corelib/kernel/qbasictimer.h @@ -43,6 +43,7 @@ #define QBASICTIMER_H #include +#include 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); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 4e8d2fc265..8db8aceced 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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); diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 3ca2e2213d..a5ac8feafd 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -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 diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 9be661e42f..e89abade2c 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -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 diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 707bc83d3c..5b7dbd1b36 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -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; } -- cgit v1.2.3