1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qtimer.h"
42 #include "qabstracteventdispatcher.h"
43 #include "qcoreapplication.h"
44 #include "qobject_p.h"
45 #include "qthread.h"
46 #include "qcoreapplication_p.h"
47 
48 QT_BEGIN_NAMESPACE
49 
50 /*!
51     \class QTimer
52     \inmodule QtCore
53     \brief The QTimer class provides repetitive and single-shot timers.
54 
55     \ingroup events
56 
57 
58     The QTimer class provides a high-level programming interface for
59     timers. To use it, create a QTimer, connect its timeout() signal
60     to the appropriate slots, and call start(). From then on, it will
61     emit the timeout() signal at constant intervals.
62 
63     Example for a one second (1000 millisecond) timer (from the
64     \l{widgets/analogclock}{Analog Clock} example):
65 
66     \snippet ../widgets/widgets/analogclock/analogclock.cpp 4
67     \snippet ../widgets/widgets/analogclock/analogclock.cpp 5
68     \snippet ../widgets/widgets/analogclock/analogclock.cpp 6
69 
70     From then on, the \c update() slot is called every second.
71 
72     You can set a timer to time out only once by calling
73     setSingleShot(true). You can also use the static
74     QTimer::singleShot() function to call a slot after a specified
75     interval:
76 
77     \snippet timers/timers.cpp 3
78 
79     In multithreaded applications, you can use QTimer in any thread
80     that has an event loop. To start an event loop from a non-GUI
81     thread, use QThread::exec(). Qt uses the timer's
82     \l{QObject::thread()}{thread affinity} to determine which thread
83     will emit the \l{QTimer::}{timeout()} signal. Because of this, you
84     must start and stop the timer in its thread; it is not possible to
85     start a timer from another thread.
86 
87     As a special case, a QTimer with a timeout of 0 will time out as soon as
88     possible, though the ordering between zero timers and other sources of
89     events is unspecified. Zero timers can be used to do some work while still
90     providing a snappy user interface:
91 
92     \snippet timers/timers.cpp 4
93     \snippet timers/timers.cpp 5
94     \snippet timers/timers.cpp 6
95 
96     From then on, \c processOneThing() will be called repeatedly. It
97     should be written in such a way that it always returns quickly
98     (typically after processing one data item) so that Qt can deliver
99     events to the user interface and stop the timer as soon as it has done all
100     its work. This is the traditional way of implementing heavy work
101     in GUI applications, but as multithreading is nowadays becoming available on
102     more and more platforms, we expect that zero-millisecond
103     QTimer objects will gradually be replaced by \l{QThread}s.
104 
105     \section1 Accuracy and Timer Resolution
106 
107     The accuracy of timers depends on the underlying operating system
108     and hardware. Most platforms support a resolution of 1 millisecond,
109     though the accuracy of the timer will not equal this resolution
110     in many real-world situations.
111 
112     The accuracy also depends on the \l{Qt::TimerType}{timer type}. For
113     Qt::PreciseTimer, QTimer will try to keep the accuracy at 1 millisecond.
114     Precise timers will also never time out earlier than expected.
115 
116     For Qt::CoarseTimer and Qt::VeryCoarseTimer types, QTimer may wake up
117     earlier than expected, within the margins for those types: 5% of the
118     interval for Qt::CoarseTimer and 500 ms for Qt::VeryCoarseTimer.
119 
120     All timer types may time out later than expected if the system is busy or
121     unable to provide the requested accuracy. In such a case of timeout
122     overrun, Qt will emit timeout() only once, even if multiple timeouts have
123     expired, and then will resume the original interval.
124 
125     \section1 Alternatives to QTimer
126 
127     An alternative to using QTimer is to call QObject::startTimer()
128     for your object and reimplement the QObject::timerEvent() event
129     handler in your class (which must inherit QObject). The
130     disadvantage is that timerEvent() does not support such
131     high-level features as single-shot timers or signals.
132 
133     Another alternative is QBasicTimer. It is typically less
134     cumbersome than using QObject::startTimer()
135     directly. See \l{Timers} for an overview of all three approaches.
136 
137     Some operating systems limit the number of timers that may be
138     used; Qt tries to work around these limitations.
139 
140     \sa QBasicTimer, QTimerEvent, QObject::timerEvent(), Timers,
141         {Analog Clock Example}, {Wiggly Example}
142 */
143 
144 static const int INV_TIMER = -1;                // invalid timer id
145 
146 /*!
147     Constructs a timer with the given \a parent.
148 */
149 
QTimer(QObject * parent)150 QTimer::QTimer(QObject *parent)
151     : QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0), type(Qt::CoarseTimer)
152 {
153     Q_UNUSED(del);  // ### Qt 6: remove field
154 }
155 
156 
157 /*!
158     Destroys the timer.
159 */
160 
~QTimer()161 QTimer::~QTimer()
162 {
163     if (id != INV_TIMER)                        // stop running timer
164         stop();
165 }
166 
167 
168 /*!
169     \fn void QTimer::timeout()
170 
171     This signal is emitted when the timer times out.
172 
173     \sa interval, start(), stop()
174 */
175 
176 /*!
177     \property QTimer::active
178     \since 4.3
179 
180     This boolean property is \c true if the timer is running; otherwise
181     false.
182 */
183 
184 /*!
185     \fn bool QTimer::isActive() const
186 
187     Returns \c true if the timer is running (pending); otherwise returns
188     false.
189 */
190 
191 /*!
192     \fn int QTimer::timerId() const
193 
194     Returns the ID of the timer if the timer is running; otherwise returns
195     -1.
196 */
197 
198 
199 /*! \overload start()
200 
201     Starts or restarts the timer with the timeout specified in \l interval.
202 
203     If the timer is already running, it will be
204     \l{QTimer::stop()}{stopped} and restarted.
205 
206     If \l singleShot is true, the timer will be activated only once.
207 */
start()208 void QTimer::start()
209 {
210     if (id != INV_TIMER)                        // stop running timer
211         stop();
212     nulltimer = (!inter && single);
213     id = QObject::startTimer(inter, Qt::TimerType(type));
214 }
215 
216 /*!
217     Starts or restarts the timer with a timeout interval of \a msec
218     milliseconds.
219 
220     If the timer is already running, it will be
221     \l{QTimer::stop()}{stopped} and restarted.
222 
223     If \l singleShot is true, the timer will be activated only once.
224 
225 */
start(int msec)226 void QTimer::start(int msec)
227 {
228     inter = msec;
229     start();
230 }
231 
232 
233 
234 /*!
235     Stops the timer.
236 
237     \sa start()
238 */
239 
stop()240 void QTimer::stop()
241 {
242     if (id != INV_TIMER) {
243         QObject::killTimer(id);
244         id = INV_TIMER;
245     }
246 }
247 
248 
249 /*!
250   \reimp
251 */
timerEvent(QTimerEvent * e)252 void QTimer::timerEvent(QTimerEvent *e)
253 {
254     if (e->timerId() == id) {
255         if (single)
256             stop();
257         emit timeout(QPrivateSignal());
258     }
259 }
260 
261 class QSingleShotTimer : public QObject
262 {
263     Q_OBJECT
264     int timerId;
265     bool hasValidReceiver;
266     QPointer<const QObject> receiver;
267     QtPrivate::QSlotObjectBase *slotObj;
268 public:
269     ~QSingleShotTimer();
270     QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char * m);
271     QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj);
272 
273 Q_SIGNALS:
274     void timeout();
275 protected:
276     void timerEvent(QTimerEvent *) override;
277 };
278 
QSingleShotTimer(int msec,Qt::TimerType timerType,const QObject * r,const char * member)279 QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char *member)
280     : QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(true), slotObj(nullptr)
281 {
282     timerId = startTimer(msec, timerType);
283     connect(this, SIGNAL(timeout()), r, member);
284 }
285 
QSingleShotTimer(int msec,Qt::TimerType timerType,const QObject * r,QtPrivate::QSlotObjectBase * slotObj)286 QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj)
287     : QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(r), receiver(r), slotObj(slotObj)
288 {
289     timerId = startTimer(msec, timerType);
290     if (r && thread() != r->thread()) {
291         // Avoid leaking the QSingleShotTimer instance in case the application exits before the timer fires
292         connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
293         setParent(nullptr);
294         moveToThread(r->thread());
295     }
296 }
297 
~QSingleShotTimer()298 QSingleShotTimer::~QSingleShotTimer()
299 {
300     if (timerId > 0)
301         killTimer(timerId);
302     if (slotObj)
303         slotObj->destroyIfLastRef();
304 }
305 
timerEvent(QTimerEvent *)306 void QSingleShotTimer::timerEvent(QTimerEvent *)
307 {
308     // need to kill the timer _before_ we emit timeout() in case the
309     // slot connected to timeout calls processEvents()
310     if (timerId > 0)
311         killTimer(timerId);
312     timerId = -1;
313 
314     if (slotObj) {
315         // If the receiver was destroyed, skip this part
316         if (Q_LIKELY(!receiver.isNull() || !hasValidReceiver)) {
317             // We allocate only the return type - we previously checked the function had
318             // no arguments.
319             void *args[1] = { nullptr };
320             slotObj->call(const_cast<QObject*>(receiver.data()), args);
321         }
322     } else {
323         emit timeout();
324     }
325 
326     // we would like to use delete later here, but it feels like a
327     // waste to post a new event to handle this event, so we just unset the flag
328     // and explicitly delete...
329     qDeleteInEventHandler(this);
330 }
331 
332 /*!
333     \internal
334 
335     Implementation of the template version of singleShot
336 
337     \a msec is the timer interval
338     \a timerType is the timer type
339     \a receiver is the receiver object, can be null. In such a case, it will be the same
340                 as the final sender class.
341     \a slot a pointer only used when using Qt::UniqueConnection
342     \a slotObj the slot object
343  */
singleShotImpl(int msec,Qt::TimerType timerType,const QObject * receiver,QtPrivate::QSlotObjectBase * slotObj)344 void QTimer::singleShotImpl(int msec, Qt::TimerType timerType,
345                             const QObject *receiver,
346                             QtPrivate::QSlotObjectBase *slotObj)
347 {
348     if (msec == 0) {
349         bool deleteReceiver = false;
350         // Optimize: set a receiver context when none is given, such that we can use
351         // QMetaObject::invokeMethod which is more efficient than going through a timer.
352         // We need a QObject living in the current thread. But the QThread itself lives
353         // in a different thread - with the exception of the main QThread which lives in
354         // itself. And QThread::currentThread() is among the few QObjects we know that will
355         // most certainly be there. Note that one can actually call singleShot before the
356         // QApplication is created!
357         if (!receiver && QThread::currentThread() == QCoreApplicationPrivate::mainThread()) {
358             // reuse main thread as context object
359             receiver = QThread::currentThread();
360         } else if (!receiver) {
361             // Create a receiver context object on-demand. According to the benchmarks,
362             // this is still more efficient than going through a timer.
363             receiver = new QObject;
364             deleteReceiver = true;
365         }
366 
367         QMetaObject::invokeMethodImpl(const_cast<QObject *>(receiver), slotObj,
368                                       Qt::QueuedConnection, nullptr);
369 
370         if (deleteReceiver)
371             const_cast<QObject *>(receiver)->deleteLater();
372         return;
373     }
374 
375     new QSingleShotTimer(msec, timerType, receiver, slotObj);
376 }
377 
378 /*!
379     \reentrant
380     This static function calls a slot after a given time interval.
381 
382     It is very convenient to use this function because you do not need
383     to bother with a \l{QObject::timerEvent()}{timerEvent} or
384     create a local QTimer object.
385 
386     Example:
387     \snippet code/src_corelib_kernel_qtimer.cpp 0
388 
389     This sample program automatically terminates after 10 minutes
390     (600,000 milliseconds).
391 
392     The \a receiver is the receiving object and the \a member is the
393     slot. The time interval is \a msec milliseconds.
394 
395     \sa start()
396 */
397 
singleShot(int msec,const QObject * receiver,const char * member)398 void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
399 {
400     // coarse timers are worst in their first firing
401     // so we prefer a high precision timer for something that happens only once
402     // unless the timeout is too big, in which case we go for coarse anyway
403     singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, receiver, member);
404 }
405 
406 /*! \overload
407     \reentrant
408     This static function calls a slot after a given time interval.
409 
410     It is very convenient to use this function because you do not need
411     to bother with a \l{QObject::timerEvent()}{timerEvent} or
412     create a local QTimer object.
413 
414     The \a receiver is the receiving object and the \a member is the slot. The
415     time interval is \a msec milliseconds. The \a timerType affects the
416     accuracy of the timer.
417 
418     \sa start()
419 */
singleShot(int msec,Qt::TimerType timerType,const QObject * receiver,const char * member)420 void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
421 {
422     if (Q_UNLIKELY(msec < 0)) {
423         qWarning("QTimer::singleShot: Timers cannot have negative timeouts");
424         return;
425     }
426     if (receiver && member) {
427         if (msec == 0) {
428             // special code shortpath for 0-timers
429             const char* bracketPosition = strchr(member, '(');
430             if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
431                 qWarning("QTimer::singleShot: Invalid slot specification");
432                 return;
433             }
434             QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name
435             QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.constData(), Qt::QueuedConnection);
436             return;
437         }
438         (void) new QSingleShotTimer(msec, timerType, receiver, member);
439     }
440 }
441 
442 /*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, const QObject *receiver, PointerToMemberFunction method)
443 
444     \since 5.4
445 
446     \overload
447     \reentrant
448     This static function calls a member function of a QObject after a given time interval.
449 
450     It is very convenient to use this function because you do not need
451     to bother with a \l{QObject::timerEvent()}{timerEvent} or
452     create a local QTimer object.
453 
454     The \a receiver is the receiving object and the \a method is the member function. The
455     time interval is \a msec milliseconds.
456 
457     If \a receiver is destroyed before the interval occurs, the method will not be called.
458     The function will be run in the thread of \a receiver. The receiver's thread must have
459     a running Qt event loop.
460 
461     \sa start()
462 */
463 
464 /*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method)
465 
466     \since 5.4
467 
468     \overload
469     \reentrant
470     This static function calls a member function of a QObject after a given time interval.
471 
472     It is very convenient to use this function because you do not need
473     to bother with a \l{QObject::timerEvent()}{timerEvent} or
474     create a local QTimer object.
475 
476     The \a receiver is the receiving object and the \a method is the member function. The
477     time interval is \a msec milliseconds. The \a timerType affects the
478     accuracy of the timer.
479 
480     If \a receiver is destroyed before the interval occurs, the method will not be called.
481     The function will be run in the thread of \a receiver. The receiver's thread must have
482     a running Qt event loop.
483 
484     \sa start()
485 */
486 
487 /*! \fn template<typename Functor> void QTimer::singleShot(int msec, Functor functor)
488 
489     \since 5.4
490 
491     \overload
492     \reentrant
493     This static function calls \a functor after a given time interval.
494 
495     It is very convenient to use this function because you do not need
496     to bother with a \l{QObject::timerEvent()}{timerEvent} or
497     create a local QTimer object.
498 
499     The time interval is \a msec milliseconds.
500 
501     \sa start()
502 */
503 
504 /*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, Functor functor)
505 
506     \since 5.4
507 
508     \overload
509     \reentrant
510     This static function calls \a functor after a given time interval.
511 
512     It is very convenient to use this function because you do not need
513     to bother with a \l{QObject::timerEvent()}{timerEvent} or
514     create a local QTimer object.
515 
516     The time interval is \a msec milliseconds. The \a timerType affects the
517     accuracy of the timer.
518 
519     \sa start()
520 */
521 
522 /*! \fn template<typename Functor> void QTimer::singleShot(int msec, const QObject *context, Functor functor)
523 
524     \since 5.4
525 
526     \overload
527     \reentrant
528     This static function calls \a functor after a given time interval.
529 
530     It is very convenient to use this function because you do not need
531     to bother with a \l{QObject::timerEvent()}{timerEvent} or
532     create a local QTimer object.
533 
534     The time interval is \a msec milliseconds.
535 
536     If \a context is destroyed before the interval occurs, the method will not be called.
537     The function will be run in the thread of \a context. The context's thread must have
538     a running Qt event loop.
539 
540     \sa start()
541 */
542 
543 /*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor)
544 
545     \since 5.4
546 
547     \overload
548     \reentrant
549     This static function calls \a functor after a given time interval.
550 
551     It is very convenient to use this function because you do not need
552     to bother with a \l{QObject::timerEvent()}{timerEvent} or
553     create a local QTimer object.
554 
555     The time interval is \a msec milliseconds. The \a timerType affects the
556     accuracy of the timer.
557 
558     If \a context is destroyed before the interval occurs, the method will not be called.
559     The function will be run in the thread of \a context. The context's thread must have
560     a running Qt event loop.
561 
562     \sa start()
563 */
564 
565 /*!
566     \fn void QTimer::singleShot(std::chrono::milliseconds msec, const QObject *receiver, const char *member)
567     \since 5.8
568     \overload
569     \reentrant
570 
571     This static function calls a slot after a given time interval.
572 
573     It is very convenient to use this function because you do not need
574     to bother with a \l{QObject::timerEvent()}{timerEvent} or
575     create a local QTimer object.
576 
577     The \a receiver is the receiving object and the \a member is the slot. The
578     time interval is given in the duration object \a msec.
579 
580     \sa start()
581 */
582 
583 /*!
584     \fn void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
585     \since 5.8
586     \overload
587     \reentrant
588 
589     This static function calls a slot after a given time interval.
590 
591     It is very convenient to use this function because you do not need
592     to bother with a \l{QObject::timerEvent()}{timerEvent} or
593     create a local QTimer object.
594 
595     The \a receiver is the receiving object and the \a member is the slot. The
596     time interval is given in the duration object \a msec. The \a timerType affects the
597     accuracy of the timer.
598 
599     \sa start()
600 */
601 
602 /*!
603     \fn template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
604     \since 5.12
605     \overload
606 
607     Creates a connection of type \a connectionType from the timeout() signal
608     to \a slot, and returns a handle to the connection.
609 
610     This method is provided for convenience.
611     It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, slot, connectionType)}.
612 
613     \sa QObject::connect(), timeout()
614 */
615 
616 /*!
617     \fn template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
618     \since 5.12
619     \overload callOnTimeout()
620 
621     Creates a connection from the timeout() signal to \a slot to be placed in a specific
622     event loop of \a context, and returns a handle to the connection.
623 
624     This method is provided for convenience. It's equivalent to calling
625     \c {QObject::connect(timer, &QTimer::timeout, context, slot, connectionType)}.
626 
627     \sa QObject::connect(), timeout()
628 */
629 
630 /*!
631     \fn template <typename MemberFunction> QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
632     \since 5.12
633     \overload callOnTimeout()
634 
635     Creates a connection from the timeout() signal to the \a slot in the \a receiver object. Returns
636     a handle to the connection.
637 
638     This method is provided for convenience. It's equivalent to calling
639     \c {QObject::connect(timer, &QTimer::timeout, receiver, slot, connectionType)}.
640 
641     \sa QObject::connect(), timeout()
642 */
643 
644 /*!
645     \fn void QTimer::start(std::chrono::milliseconds msec)
646     \since 5.8
647     \overload
648 
649     Starts or restarts the timer with a timeout of duration \a msec milliseconds.
650 
651     If the timer is already running, it will be
652     \l{QTimer::stop()}{stopped} and restarted.
653 
654     If \l singleShot is true, the timer will be activated only once.
655 */
656 
657 /*!
658     \fn std::chrono::milliseconds QTimer::intervalAsDuration() const
659     \since 5.8
660 
661     Returns the interval of this timer as a \c std::chrono::milliseconds object.
662 
663     \sa interval
664 */
665 
666 /*!
667     \fn std::chrono::milliseconds QTimer::remainingTimeAsDuration() const
668     \since 5.8
669 
670     Returns the time remaining in this timer object as a \c
671     std::chrono::milliseconds object. If this timer is due or overdue, the
672     returned value is \c std::chrono::milliseconds::zero(). If the remaining
673     time could not be found or the timer is not active, this function returns a
674     negative duration.
675 
676     \sa remainingTime()
677 */
678 
679 /*!
680     \property QTimer::singleShot
681     \brief whether the timer is a single-shot timer
682 
683     A single-shot timer fires only once, non-single-shot timers fire
684     every \l interval milliseconds.
685 
686     The default value for this property is \c false.
687 
688     \sa interval, singleShot()
689 */
690 
691 /*!
692     \property QTimer::interval
693     \brief the timeout interval in milliseconds
694 
695     The default value for this property is 0.  A QTimer with a timeout
696     interval of 0 will time out as soon as all the events in the window
697     system's event queue have been processed.
698 
699     Setting the interval of an active timer changes its timerId().
700 
701     \sa singleShot
702 */
setInterval(int msec)703 void QTimer::setInterval(int msec)
704 {
705     inter = msec;
706     if (id != INV_TIMER) {                        // create new timer
707         QObject::killTimer(id);                        // restart timer
708         id = QObject::startTimer(msec, Qt::TimerType(type));
709     }
710 }
711 
712 /*!
713     \property QTimer::remainingTime
714     \since 5.0
715     \brief the remaining time in milliseconds
716 
717     Returns the timer's remaining value in milliseconds left until the timeout.
718     If the timer is inactive, the returned value will be -1. If the timer is
719     overdue, the returned value will be 0.
720 
721     \sa interval
722 */
remainingTime() const723 int QTimer::remainingTime() const
724 {
725     if (id != INV_TIMER) {
726         return QAbstractEventDispatcher::instance()->remainingTime(id);
727     }
728 
729     return -1;
730 }
731 
732 /*!
733     \property QTimer::timerType
734     \brief controls the accuracy of the timer
735 
736     The default value for this property is \c Qt::CoarseTimer.
737 
738     \sa Qt::TimerType
739 */
740 
741 QT_END_NAMESPACE
742 
743 #include "qtimer.moc"
744 #include "moc_qtimer.cpp"
745