kernel/qtimer.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qtimer.h" -
43#include "qabstracteventdispatcher.h" -
44#include "qcoreapplication.h" -
45#include "qobject_p.h" -
46 -
47QT_BEGIN_NAMESPACE -
48 -
49/*! -
50 \class QTimer -
51 \inmodule QtCore -
52 \brief The QTimer class provides repetitive and single-shot timers. -
53 -
54 \ingroup events -
55 -
56 -
57 The QTimer class provides a high-level programming interface for -
58 timers. To use it, create a QTimer, connect its timeout() signal -
59 to the appropriate slots, and call start(). From then on, it will -
60 emit the timeout() signal at constant intervals. -
61 -
62 Example for a one second (1000 millisecond) timer (from the -
63 \l{widgets/analogclock}{Analog Clock} example): -
64 -
65 \snippet ../widgets/widgets/analogclock/analogclock.cpp 4 -
66 \snippet ../widgets/widgets/analogclock/analogclock.cpp 5 -
67 \snippet ../widgets/widgets/analogclock/analogclock.cpp 6 -
68 -
69 From then on, the \c update() slot is called every second. -
70 -
71 You can set a timer to time out only once by calling -
72 setSingleShot(true). You can also use the static -
73 QTimer::singleShot() function to call a slot after a specified -
74 interval: -
75 -
76 \snippet timers/timers.cpp 3 -
77 -
78 In multithreaded applications, you can use QTimer in any thread -
79 that has an event loop. To start an event loop from a non-GUI -
80 thread, use QThread::exec(). Qt uses the timer's -
81 \l{QObject::thread()}{thread affinity} to determine which thread -
82 will emit the \l{QTimer::}{timeout()} signal. Because of this, you -
83 must start and stop the timer in its thread; it is not possible to -
84 start a timer from another thread. -
85 -
86 As a special case, a QTimer with a timeout of 0 will time out as -
87 soon as all the events in the window system's event queue have -
88 been processed. This can be used to do heavy work while providing -
89 a snappy user interface: -
90 -
91 \snippet timers/timers.cpp 4 -
92 \snippet timers/timers.cpp 5 -
93 \snippet timers/timers.cpp 6 -
94 -
95 From then on, \c processOneThing() will be called repeatedly. It -
96 should be written in such a way that it always returns quickly -
97 (typically after processing one data item) so that Qt can deliver -
98 events to the user interface and stop the timer as soon as it has done all -
99 its work. This is the traditional way of implementing heavy work -
100 in GUI applications, but as multithreading is nowadays becoming available on -
101 more and more platforms, we expect that zero-millisecond -
102 QTimers will gradually be replaced by \l{QThread}s. -
103 -
104 \section1 Accuracy and Timer Resolution -
105 -
106 Timers will never time out earlier than the specified timeout value -
107 and they are not guaranteed to time out at the exact value specified. -
108 In many situations, they may time out late by a period of time that -
109 depends on the accuracy of the system timers. -
110 -
111 The accuracy of timers depends on the underlying operating system -
112 and hardware. Most platforms support a resolution of 1 millisecond, -
113 though the accuracy of the timer will not equal this resolution -
114 in many real-world situations. -
115 -
116 If Qt is unable to deliver the requested number of timer clicks, -
117 it will silently discard some. -
118 -
119 \section1 Alternatives to QTimer -
120 -
121 An alternative to using QTimer is to call QObject::startTimer() -
122 for your object and reimplement the QObject::timerEvent() event -
123 handler in your class (which must inherit QObject). The -
124 disadvantage is that timerEvent() does not support such -
125 high-level features as single-shot timers or signals. -
126 -
127 Another alternative is QBasicTimer. It is typically less -
128 cumbersome than using QObject::startTimer() -
129 directly. See \l{Timers} for an overview of all three approaches. -
130 -
131 Some operating systems limit the number of timers that may be -
132 used; Qt tries to work around these limitations. -
133 -
134 \sa QBasicTimer, QTimerEvent, QObject::timerEvent(), Timers, -
135 {Analog Clock Example}, {Wiggly Example} -
136*/ -
137 -
138static const int INV_TIMER = -1; // invalid timer id -
139 -
140/*! -
141 Constructs a timer with the given \a parent. -
142*/ -
143 -
144QTimer::QTimer(QObject *parent) -
145 : QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0), type(Qt::CoarseTimer) -
146{ -
147}
executed: }
Execution Count:3241
3241
148 -
149 -
150/*! -
151 Destroys the timer. -
152*/ -
153 -
154QTimer::~QTimer() -
155{ -
156 if (id != INV_TIMER) // stop running timer
evaluated: id != INV_TIMER
TRUEFALSE
yes
Evaluation Count:235
yes
Evaluation Count:3004
235-3004
157 stop();
executed: stop();
Execution Count:235
235
158}
executed: }
Execution Count:3239
3239
159 -
160 -
161/*! -
162 \fn void QTimer::timeout() -
163 -
164 This signal is emitted when the timer times out. -
165 -
166 \sa interval, start(), stop() -
167*/ -
168 -
169/*! -
170 \property QTimer::active -
171 \since 4.3 -
172 -
173 This boolean property is true if the timer is running; otherwise -
174 false. -
175*/ -
176 -
177/*! -
178 \fn bool QTimer::isActive() const -
179 -
180 Returns true if the timer is running (pending); otherwise returns -
181 false. -
182*/ -
183 -
184/*! -
185 \fn int QTimer::timerId() const -
186 -
187 Returns the ID of the timer if the timer is running; otherwise returns -
188 -1. -
189*/ -
190 -
191 -
192/*! \overload start() -
193 -
194 Starts or restarts the timer with the timeout specified in \l interval. -
195 -
196 If the timer is already running, it will be -
197 \l{QTimer::stop()}{stopped} and restarted. -
198 -
199 If \l singleShot is true, the timer will be activated only once. -
200*/ -
201void QTimer::start() -
202{ -
203 if (id != INV_TIMER) // stop running timer
evaluated: id != INV_TIMER
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:2745
10-2745
204 stop();
executed: stop();
Execution Count:10
10
205 nulltimer = (!inter && single);
evaluated: !inter
TRUEFALSE
yes
Evaluation Count:345
yes
Evaluation Count:2410
evaluated: single
TRUEFALSE
yes
Evaluation Count:341
yes
Evaluation Count:4
4-2410
206 id = QObject::startTimer(inter, Qt::TimerType(type));
executed (the execution status of this line is deduced): id = QObject::startTimer(inter, Qt::TimerType(type));
-
207}
executed: }
Execution Count:2755
2755
208 -
209/*! -
210 Starts or restarts the timer with a timeout interval of \a msec -
211 milliseconds. -
212 -
213 If the timer is already running, it will be -
214 \l{QTimer::stop()}{stopped} and restarted. -
215 -
216 If \l singleShot is true, the timer will be activated only once. -
217 -
218*/ -
219void QTimer::start(int msec) -
220{ -
221 inter = msec;
executed (the execution status of this line is deduced): inter = msec;
-
222 start();
executed (the execution status of this line is deduced): start();
-
223}
executed: }
Execution Count:2637
2637
224 -
225 -
226 -
227/*! -
228 Stops the timer. -
229 -
230 \sa start() -
231*/ -
232 -
233void QTimer::stop() -
234{ -
235 if (id != INV_TIMER) {
evaluated: id != INV_TIMER
TRUEFALSE
yes
Evaluation Count:2756
yes
Evaluation Count:1499
1499-2756
236 QObject::killTimer(id);
executed (the execution status of this line is deduced): QObject::killTimer(id);
-
237 id = INV_TIMER;
executed (the execution status of this line is deduced): id = INV_TIMER;
-
238 }
executed: }
Execution Count:2756
2756
239}
executed: }
Execution Count:4255
4255
240 -
241 -
242/*! -
243 \reimp -
244*/ -
245void QTimer::timerEvent(QTimerEvent *e) -
246{ -
247 if (e->timerId() == id) {
partially evaluated: e->timerId() == id
TRUEFALSE
yes
Evaluation Count:26551
no
Evaluation Count:0
0-26551
248 if (single)
evaluated: single
TRUEFALSE
yes
Evaluation Count:400
yes
Evaluation Count:26151
400-26151
249 stop();
executed: stop();
Execution Count:400
400
250 emit timeout(QPrivateSignal());
executed (the execution status of this line is deduced): timeout(QPrivateSignal());
-
251 }
executed: }
Execution Count:26551
26551
252}
executed: }
Execution Count:26551
26551
253 -
254class QSingleShotTimer : public QObject -
255{ -
256 Q_OBJECT -
257 int timerId; -
258public: -
259 ~QSingleShotTimer(); -
260 QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char * m); -
261Q_SIGNALS: -
262 void timeout(); -
263protected: -
264 void timerEvent(QTimerEvent *); -
265}; -
266 -
267QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) -
268 : QObject(QAbstractEventDispatcher::instance()) -
269{ -
270 connect(this, SIGNAL(timeout()), receiver, member);
executed (the execution status of this line is deduced): connect(this, "2""timeout()", receiver, member);
-
271 timerId = startTimer(msec, timerType);
executed (the execution status of this line is deduced): timerId = startTimer(msec, timerType);
-
272}
executed: }
Execution Count:1349
1349
273 -
274QSingleShotTimer::~QSingleShotTimer() -
275{ -
276 if (timerId > 0)
evaluated: timerId > 0
TRUEFALSE
yes
Evaluation Count:109
yes
Evaluation Count:1240
109-1240
277 killTimer(timerId);
executed: killTimer(timerId);
Execution Count:109
109
278}
executed: }
Execution Count:1349
1349
279 -
280void QSingleShotTimer::timerEvent(QTimerEvent *) -
281{ -
282 // need to kill the timer _before_ we emit timeout() in case the -
283 // slot connected to timeout calls processEvents() -
284 if (timerId > 0)
partially evaluated: timerId > 0
TRUEFALSE
yes
Evaluation Count:1240
no
Evaluation Count:0
0-1240
285 killTimer(timerId);
executed: killTimer(timerId);
Execution Count:1240
1240
286 timerId = -1;
executed (the execution status of this line is deduced): timerId = -1;
-
287 emit timeout();
executed (the execution status of this line is deduced): timeout();
-
288 -
289 // we would like to use delete later here, but it feels like a -
290 // waste to post a new event to handle this event, so we just unset the flag -
291 // and explicitly delete... -
292 qDeleteInEventHandler(this);
executed (the execution status of this line is deduced): qDeleteInEventHandler(this);
-
293}
executed: }
Execution Count:1240
1240
294 -
295/*! -
296 \reentrant -
297 This static function calls a slot after a given time interval. -
298 -
299 It is very convenient to use this function because you do not need -
300 to bother with a \l{QObject::timerEvent()}{timerEvent} or -
301 create a local QTimer object. -
302 -
303 Example: -
304 \snippet code/src_corelib_kernel_qtimer.cpp 0 -
305 -
306 This sample program automatically terminates after 10 minutes -
307 (600,000 milliseconds). -
308 -
309 The \a receiver is the receiving object and the \a member is the -
310 slot. The time interval is \a msec milliseconds. -
311 -
312 \sa start() -
313*/ -
314 -
315void QTimer::singleShot(int msec, const QObject *receiver, const char *member) -
316{ -
317 // coarse timers are worst in their first firing -
318 // so we prefer a high precision timer for something that happens only once -
319 // unless the timeout is too big, in which case we go for coarse anyway -
320 singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, receiver, member);
executed (the execution status of this line is deduced): singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, receiver, member);
-
321}
executed: }
Execution Count:2957
2957
322 -
323/*! \overload -
324 \reentrant -
325 This static function calls a slot after a given time interval. -
326 -
327 It is very convenient to use this function because you do not need -
328 to bother with a \l{QObject::timerEvent()}{timerEvent} or -
329 create a local QTimer object. -
330 -
331 The \a receiver is the receiving object and the \a member is the slot. The -
332 time interval is \a msec milliseconds. The \a timerType affects the -
333 accuracy of the timer. -
334 -
335 \sa start() -
336*/ -
337void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) -
338{ -
339 if (receiver && member) {
partially evaluated: receiver
TRUEFALSE
yes
Evaluation Count:2957
no
Evaluation Count:0
partially evaluated: member
TRUEFALSE
yes
Evaluation Count:2957
no
Evaluation Count:0
0-2957
340 if (msec == 0) {
evaluated: msec == 0
TRUEFALSE
yes
Evaluation Count:1608
yes
Evaluation Count:1349
1349-1608
341 // special code shortpath for 0-timers -
342 const char* bracketPosition = strchr(member, '(');
executed (the execution status of this line is deduced): const char* bracketPosition = strchr(member, '(');
-
343 if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
partially evaluated: !bracketPosition
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1608
partially evaluated: member[0] >= '0'
TRUEFALSE
yes
Evaluation Count:1608
no
Evaluation Count:0
partially evaluated: member[0] <= '2'
TRUEFALSE
yes
Evaluation Count:1608
no
Evaluation Count:0
0-1608
344 qWarning("QTimer::singleShot: Invalid slot specification");
never executed (the execution status of this line is deduced): QMessageLogger("kernel/qtimer.cpp", 344, __PRETTY_FUNCTION__).warning("QTimer::singleShot: Invalid slot specification");
-
345 return;
never executed: return;
0
346 } -
347 QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name
executed (the execution status of this line is deduced): QByteArray methodName(member+1, bracketPosition - 1 - member);
-
348 QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.constData(), Qt::QueuedConnection);
executed (the execution status of this line is deduced): QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.constData(), Qt::QueuedConnection);
-
349 return;
executed: return;
Execution Count:1608
1608
350 } -
351 (void) new QSingleShotTimer(msec, timerType, receiver, member);
executed (the execution status of this line is deduced): (void) new QSingleShotTimer(msec, timerType, receiver, member);
-
352 }
executed: }
Execution Count:1349
1349
353}
executed: }
Execution Count:1349
1349
354 -
355/*! -
356 \property QTimer::singleShot -
357 \brief whether the timer is a single-shot timer -
358 -
359 A single-shot timer fires only once, non-single-shot timers fire -
360 every \l interval milliseconds. -
361 -
362 \sa interval, singleShot() -
363*/ -
364 -
365/*! -
366 \property QTimer::interval -
367 \brief the timeout interval in milliseconds -
368 -
369 The default value for this property is 0. A QTimer with a timeout -
370 interval of 0 will time out as soon as all the events in the window -
371 system's event queue have been processed. -
372 -
373 Setting the interval of an active timer changes its timerId(). -
374 -
375 \sa singleShot -
376*/ -
377void QTimer::setInterval(int msec) -
378{ -
379 inter = msec;
executed (the execution status of this line is deduced): inter = msec;
-
380 if (id != INV_TIMER) { // create new timer
partially evaluated: id != INV_TIMER
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:46
0-46
381 QObject::killTimer(id); // restart timer
never executed (the execution status of this line is deduced): QObject::killTimer(id);
-
382 id = QObject::startTimer(msec, Qt::TimerType(type));
never executed (the execution status of this line is deduced): id = QObject::startTimer(msec, Qt::TimerType(type));
-
383 }
never executed: }
0
384}
executed: }
Execution Count:46
46
385 -
386/*! -
387 \property QTimer::remainingTime -
388 \since 5.0 -
389 \brief the remaining time in milliseconds -
390 -
391 Returns the timer's remaining value in milliseconds left until the timeout. -
392 If the timer is inactive, the returned value will be -1. If the timer is -
393 overdue, the returned value will be 0. -
394 -
395 \sa interval -
396*/ -
397int QTimer::remainingTime() const -
398{ -
399 if (id != INV_TIMER) {
partially evaluated: id != INV_TIMER
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
400 return QAbstractEventDispatcher::instance()->remainingTime(id);
executed: return QAbstractEventDispatcher::instance()->remainingTime(id);
Execution Count:1
1
401 } -
402 -
403 return -1;
never executed: return -1;
0
404} -
405 -
406/*! -
407 \property QTimer::timerType -
408 \brief controls the accuracy of the timer -
409 -
410 The default value for this property is \c Qt::CoarseTimer. -
411 -
412 \sa Qt::TimerType -
413*/ -
414 -
415QT_END_NAMESPACE -
416 -
417#include "qtimer.moc" -
418 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial