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 | static constexpr int INV_TIMER = -1; // invalid timer id |
51 | |
52 | class QTimerPrivate : public QObjectPrivate |
53 | { |
54 | public: |
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 | |
160 | QTimer::QTimer(QObject *parent) |
161 | : QObject(*new QTimerPrivate, parent) |
162 | { |
163 | } |
164 | |
165 | |
166 | /*! |
167 | Destroys the timer. |
168 | */ |
169 | |
170 | QTimer::~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 | */ |
199 | bool 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 | */ |
210 | int 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 | */ |
225 | void 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 | */ |
244 | void 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 | |
259 | void 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 | */ |
272 | void 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 | |
282 | class QSingleShotTimer : public QObject |
283 | { |
284 | Q_OBJECT |
285 | int timerId; |
286 | bool hasValidReceiver; |
287 | QPointer<const QObject> receiver; |
288 | QtPrivate::QSlotObjectBase *slotObj; |
289 | public: |
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 | |
294 | Q_SIGNALS: |
295 | void timeout(); |
296 | protected: |
297 | void timerEvent(QTimerEvent *) override; |
298 | }; |
299 | |
300 | QSingleShotTimer::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 | |
307 | QSingleShotTimer::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 | |
319 | QSingleShotTimer::~QSingleShotTimer() |
320 | { |
321 | if (timerId > 0) |
322 | killTimer(timerId); |
323 | if (slotObj) |
324 | slotObj->destroyIfLastRef(); |
325 | } |
326 | |
327 | void 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 | */ |
365 | void 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 | |
419 | void 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 | */ |
441 | void 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 | */ |
711 | void QTimer::setSingleShot(bool singleShot) |
712 | { |
713 | d_func()->single = singleShot; |
714 | } |
715 | |
716 | bool 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 | */ |
733 | void 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 | |
743 | int 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 | */ |
759 | int 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 | */ |
777 | void QTimer::setTimerType(Qt::TimerType atype) |
778 | { |
779 | d_func()->type = atype; |
780 | } |
781 | |
782 | Qt::TimerType QTimer::timerType() const |
783 | { |
784 | return d_func()->type; |
785 | } |
786 | |
787 | QT_END_NAMESPACE |
788 | |
789 | #include "qtimer.moc" |
790 | #include "moc_qtimer.cpp" |
791 | |