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 | |
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 | |
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 | */ |
208 | void QTimer::start() |
209 | { |
210 | if (id != INV_TIMER) // stop running timer |
211 | stop(); |
212 | nulltimer = (!inter && single); |
213 | id = QObject::startTimer(interval: inter, timerType: 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 | */ |
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 | |
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 | */ |
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 | |
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(interval: msec, timerType); |
283 | connect(sender: this, SIGNAL(timeout()), receiver: r, member); |
284 | } |
285 | |
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(interval: 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(sender: QCoreApplication::instance(), signal: &QCoreApplication::aboutToQuit, receiver: this, slot: &QObject::deleteLater); |
293 | setParent(nullptr); |
294 | moveToThread(thread: r->thread()); |
295 | } |
296 | } |
297 | |
298 | QSingleShotTimer::~QSingleShotTimer() |
299 | { |
300 | if (timerId > 0) |
301 | killTimer(id: timerId); |
302 | if (slotObj) |
303 | slotObj->destroyIfLastRef(); |
304 | } |
305 | |
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(id: 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(r: const_cast<QObject*>(receiver.data()), a: 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(o: 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 | */ |
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(object: const_cast<QObject *>(receiver), slot: slotObj, |
368 | type: Qt::QueuedConnection, ret: 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 | |
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, timerType: 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 | */ |
420 | void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) |
421 | { |
422 | if (Q_UNLIKELY(msec < 0)) { |
423 | qWarning(msg: "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(s: member, c: '('); |
430 | if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) { |
431 | qWarning(msg: "QTimer::singleShot: Invalid slot specification" ); |
432 | return; |
433 | } |
434 | QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name |
435 | QMetaObject::invokeMethod(obj: const_cast<QObject *>(receiver), member: methodName.constData(), type: 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 | */ |
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(interval: msec, timerType: 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 | */ |
723 | int QTimer::remainingTime() const |
724 | { |
725 | if (id != INV_TIMER) { |
726 | return QAbstractEventDispatcher::instance()->remainingTime(timerId: 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 | |