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