2011-04-27 10:05:43 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2016-01-15 07:08:27 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
2016-01-21 02:33:50 +00:00
|
|
|
** Copyright (C) 2016 Intel Corporation.
|
2016-01-15 07:08:27 +00:00
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-04-27 10:05:43 +00:00
|
|
|
**
|
|
|
|
** This file is part of the QtCore module of the Qt Toolkit.
|
|
|
|
**
|
2016-01-15 07:08:27 +00:00
|
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
2012-09-19 12:28:29 +00:00
|
|
|
** Commercial License Usage
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2015-01-28 08:44:43 +00:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
2016-01-15 07:08:27 +00:00
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2012-09-19 12:28:29 +00:00
|
|
|
**
|
2011-04-27 10:05:43 +00:00
|
|
|
** GNU Lesser General Public License Usage
|
2012-09-19 12:28:29 +00:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
2016-01-15 07:08:27 +00:00
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU Lesser General Public License version 3 requirements
|
|
|
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
2012-09-19 12:28:29 +00:00
|
|
|
**
|
2016-01-15 07:08:27 +00:00
|
|
|
** GNU General Public License Usage
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
** General Public License version 2.0 or (at your option) the GNU General
|
|
|
|
** Public license version 3 or any later version approved by the KDE Free
|
|
|
|
** Qt Foundation. The licenses are as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
|
|
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
2011-04-27 10:05:43 +00:00
|
|
|
**
|
|
|
|
** $QT_END_LICENSE$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "qtimer.h"
|
|
|
|
#include "qabstracteventdispatcher.h"
|
|
|
|
#include "qcoreapplication.h"
|
|
|
|
#include "qobject_p.h"
|
|
|
|
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class QTimer
|
2012-08-23 10:22:38 +00:00
|
|
|
\inmodule QtCore
|
2011-04-27 10:05:43 +00:00
|
|
|
\brief The QTimer class provides repetitive and single-shot timers.
|
|
|
|
|
|
|
|
\ingroup events
|
|
|
|
|
|
|
|
|
|
|
|
The QTimer class provides a high-level programming interface for
|
|
|
|
timers. To use it, create a QTimer, connect its timeout() signal
|
2012-09-08 17:06:23 +00:00
|
|
|
to the appropriate slots, and call start(). From then on, it will
|
2011-04-27 10:05:43 +00:00
|
|
|
emit the timeout() signal at constant intervals.
|
|
|
|
|
|
|
|
Example for a one second (1000 millisecond) timer (from the
|
|
|
|
\l{widgets/analogclock}{Analog Clock} example):
|
|
|
|
|
2012-12-12 15:56:53 +00:00
|
|
|
\snippet ../widgets/widgets/analogclock/analogclock.cpp 4
|
|
|
|
\snippet ../widgets/widgets/analogclock/analogclock.cpp 5
|
|
|
|
\snippet ../widgets/widgets/analogclock/analogclock.cpp 6
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
From then on, the \c update() slot is called every second.
|
|
|
|
|
|
|
|
You can set a timer to time out only once by calling
|
|
|
|
setSingleShot(true). You can also use the static
|
|
|
|
QTimer::singleShot() function to call a slot after a specified
|
|
|
|
interval:
|
|
|
|
|
2012-03-20 18:37:07 +00:00
|
|
|
\snippet timers/timers.cpp 3
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
In multithreaded applications, you can use QTimer in any thread
|
|
|
|
that has an event loop. To start an event loop from a non-GUI
|
|
|
|
thread, use QThread::exec(). Qt uses the timer's
|
|
|
|
\l{QObject::thread()}{thread affinity} to determine which thread
|
|
|
|
will emit the \l{QTimer::}{timeout()} signal. Because of this, you
|
|
|
|
must start and stop the timer in its thread; it is not possible to
|
|
|
|
start a timer from another thread.
|
|
|
|
|
|
|
|
As a special case, a QTimer with a timeout of 0 will time out as
|
|
|
|
soon as all the events in the window system's event queue have
|
|
|
|
been processed. This can be used to do heavy work while providing
|
|
|
|
a snappy user interface:
|
|
|
|
|
2012-03-20 18:37:07 +00:00
|
|
|
\snippet timers/timers.cpp 4
|
|
|
|
\snippet timers/timers.cpp 5
|
|
|
|
\snippet timers/timers.cpp 6
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2012-09-08 17:06:23 +00:00
|
|
|
From then on, \c processOneThing() will be called repeatedly. It
|
2011-04-27 10:05:43 +00:00
|
|
|
should be written in such a way that it always returns quickly
|
|
|
|
(typically after processing one data item) so that Qt can deliver
|
2012-09-08 17:06:23 +00:00
|
|
|
events to the user interface and stop the timer as soon as it has done all
|
2011-04-27 10:05:43 +00:00
|
|
|
its work. This is the traditional way of implementing heavy work
|
2012-09-08 17:06:23 +00:00
|
|
|
in GUI applications, but as multithreading is nowadays becoming available on
|
|
|
|
more and more platforms, we expect that zero-millisecond
|
2015-01-21 14:42:19 +00:00
|
|
|
QTimer objects will gradually be replaced by \l{QThread}s.
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
\section1 Accuracy and Timer Resolution
|
|
|
|
|
|
|
|
The accuracy of timers depends on the underlying operating system
|
|
|
|
and hardware. Most platforms support a resolution of 1 millisecond,
|
|
|
|
though the accuracy of the timer will not equal this resolution
|
|
|
|
in many real-world situations.
|
|
|
|
|
2013-10-01 18:25:48 +00:00
|
|
|
The accuracy also depends on the \l{Qt::TimerType}{timer type}. For
|
|
|
|
Qt::PreciseTimer, QTimer will try to keep the accurance at 1 millisecond.
|
|
|
|
Precise timers will also never time out earlier than expected.
|
|
|
|
|
|
|
|
For Qt::CoarseTimer and Qt::VeryCoarseTimer types, QTimer may wake up
|
|
|
|
earlier than expected, within the margins for those types: 5% of the
|
|
|
|
interval for Qt::CoarseTimer and 500 ms for Qt::VeryCoarseTimer.
|
|
|
|
|
|
|
|
All timer types may time out later than expected if the system is busy or
|
|
|
|
unable to provide the requested accuracy. In such a case of timeout
|
|
|
|
overrun, Qt will emit activated() only once, even if multiple timeouts have
|
|
|
|
expired, and then will resume the original interval.
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
\section1 Alternatives to QTimer
|
|
|
|
|
|
|
|
An alternative to using QTimer is to call QObject::startTimer()
|
|
|
|
for your object and reimplement the QObject::timerEvent() event
|
|
|
|
handler in your class (which must inherit QObject). The
|
|
|
|
disadvantage is that timerEvent() does not support such
|
|
|
|
high-level features as single-shot timers or signals.
|
|
|
|
|
2012-09-08 17:06:23 +00:00
|
|
|
Another alternative is QBasicTimer. It is typically less
|
|
|
|
cumbersome than using QObject::startTimer()
|
2011-04-27 10:05:43 +00:00
|
|
|
directly. See \l{Timers} for an overview of all three approaches.
|
|
|
|
|
|
|
|
Some operating systems limit the number of timers that may be
|
|
|
|
used; Qt tries to work around these limitations.
|
|
|
|
|
|
|
|
\sa QBasicTimer, QTimerEvent, QObject::timerEvent(), Timers,
|
|
|
|
{Analog Clock Example}, {Wiggly Example}
|
|
|
|
*/
|
|
|
|
|
|
|
|
static const int INV_TIMER = -1; // invalid timer id
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a timer with the given \a parent.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTimer::QTimer(QObject *parent)
|
2011-12-21 10:32:43 +00:00
|
|
|
: QObject(parent), id(INV_TIMER), inter(0), del(0), single(0), nulltimer(0), type(Qt::CoarseTimer)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2017-04-25 18:02:47 +00:00
|
|
|
Q_UNUSED(del); // ### Qt 6: remove field
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Destroys the timer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
QTimer::~QTimer()
|
|
|
|
{
|
|
|
|
if (id != INV_TIMER) // stop running timer
|
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn void QTimer::timeout()
|
|
|
|
|
|
|
|
This signal is emitted when the timer times out.
|
|
|
|
|
|
|
|
\sa interval, start(), stop()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\property QTimer::active
|
|
|
|
\since 4.3
|
|
|
|
|
2013-10-02 14:51:05 +00:00
|
|
|
This boolean property is \c true if the timer is running; otherwise
|
2011-04-27 10:05:43 +00:00
|
|
|
false.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn bool QTimer::isActive() const
|
|
|
|
|
2013-10-02 14:51:05 +00:00
|
|
|
Returns \c true if the timer is running (pending); otherwise returns
|
2011-04-27 10:05:43 +00:00
|
|
|
false.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn int QTimer::timerId() const
|
|
|
|
|
|
|
|
Returns the ID of the timer if the timer is running; otherwise returns
|
|
|
|
-1.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*! \overload start()
|
|
|
|
|
|
|
|
Starts or restarts the timer with the timeout specified in \l interval.
|
|
|
|
|
2011-05-10 17:52:50 +00:00
|
|
|
If the timer is already running, it will be
|
|
|
|
\l{QTimer::stop()}{stopped} and restarted.
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
If \l singleShot is true, the timer will be activated only once.
|
|
|
|
*/
|
|
|
|
void QTimer::start()
|
|
|
|
{
|
|
|
|
if (id != INV_TIMER) // stop running timer
|
|
|
|
stop();
|
|
|
|
nulltimer = (!inter && single);
|
2011-12-21 10:32:43 +00:00
|
|
|
id = QObject::startTimer(inter, Qt::TimerType(type));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Starts or restarts the timer with a timeout interval of \a msec
|
|
|
|
milliseconds.
|
2011-05-10 17:52:50 +00:00
|
|
|
|
|
|
|
If the timer is already running, it will be
|
|
|
|
\l{QTimer::stop()}{stopped} and restarted.
|
|
|
|
|
|
|
|
If \l singleShot is true, the timer will be activated only once.
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
*/
|
|
|
|
void QTimer::start(int msec)
|
|
|
|
{
|
|
|
|
inter = msec;
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Stops the timer.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
|
|
|
void QTimer::stop()
|
|
|
|
{
|
|
|
|
if (id != INV_TIMER) {
|
|
|
|
QObject::killTimer(id);
|
|
|
|
id = INV_TIMER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\reimp
|
|
|
|
*/
|
|
|
|
void QTimer::timerEvent(QTimerEvent *e)
|
|
|
|
{
|
|
|
|
if (e->timerId() == id) {
|
|
|
|
if (single)
|
|
|
|
stop();
|
2012-10-18 12:29:06 +00:00
|
|
|
emit timeout(QPrivateSignal());
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class QSingleShotTimer : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
int timerId;
|
2013-09-21 19:01:58 +00:00
|
|
|
bool hasValidReceiver;
|
|
|
|
QPointer<const QObject> receiver;
|
|
|
|
QtPrivate::QSlotObjectBase *slotObj;
|
2011-04-27 10:05:43 +00:00
|
|
|
public:
|
|
|
|
~QSingleShotTimer();
|
2012-09-13 18:23:10 +00:00
|
|
|
QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char * m);
|
2013-09-21 19:01:58 +00:00
|
|
|
QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj);
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
Q_SIGNALS:
|
|
|
|
void timeout();
|
|
|
|
protected:
|
2017-09-18 08:36:49 +00:00
|
|
|
void timerEvent(QTimerEvent *) override;
|
2011-04-27 10:05:43 +00:00
|
|
|
};
|
|
|
|
|
2013-09-21 19:01:58 +00:00
|
|
|
QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char *member)
|
|
|
|
: QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(true), slotObj(0)
|
|
|
|
{
|
|
|
|
timerId = startTimer(msec, timerType);
|
|
|
|
connect(this, SIGNAL(timeout()), r, member);
|
|
|
|
}
|
|
|
|
|
|
|
|
QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj)
|
|
|
|
: QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(r), receiver(r), slotObj(slotObj)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2011-12-21 10:32:43 +00:00
|
|
|
timerId = startTimer(msec, timerType);
|
2013-09-21 19:01:58 +00:00
|
|
|
if (r && thread() != r->thread()) {
|
2015-10-12 03:29:51 +00:00
|
|
|
// Avoid leaking the QSingleShotTimer instance in case the application exits before the timer fires
|
|
|
|
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
|
2013-09-21 19:01:58 +00:00
|
|
|
setParent(0);
|
|
|
|
moveToThread(r->thread());
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QSingleShotTimer::~QSingleShotTimer()
|
|
|
|
{
|
|
|
|
if (timerId > 0)
|
|
|
|
killTimer(timerId);
|
2013-09-21 19:01:58 +00:00
|
|
|
if (slotObj)
|
|
|
|
slotObj->destroyIfLastRef();
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void QSingleShotTimer::timerEvent(QTimerEvent *)
|
|
|
|
{
|
|
|
|
// need to kill the timer _before_ we emit timeout() in case the
|
|
|
|
// slot connected to timeout calls processEvents()
|
|
|
|
if (timerId > 0)
|
|
|
|
killTimer(timerId);
|
|
|
|
timerId = -1;
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
if (slotObj) {
|
|
|
|
// If the receiver was destroyed, skip this part
|
|
|
|
if (Q_LIKELY(!receiver.isNull() || !hasValidReceiver)) {
|
|
|
|
// We allocate only the return type - we previously checked the function had
|
|
|
|
// no arguments.
|
|
|
|
void *args[1] = { 0 };
|
|
|
|
slotObj->call(const_cast<QObject*>(receiver.data()), args);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
emit timeout();
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
// we would like to use delete later here, but it feels like a
|
|
|
|
// waste to post a new event to handle this event, so we just unset the flag
|
|
|
|
// and explicitly delete...
|
|
|
|
qDeleteInEventHandler(this);
|
|
|
|
}
|
|
|
|
|
2013-09-21 19:01:58 +00:00
|
|
|
/*!
|
|
|
|
\internal
|
|
|
|
|
|
|
|
Implementation of the template version of singleShot
|
|
|
|
|
|
|
|
\a msec is the timer interval
|
|
|
|
\a timerType is the timer type
|
|
|
|
\a receiver is the receiver object, can be null. In such a case, it will be the same
|
|
|
|
as the final sender class.
|
|
|
|
\a slot a pointer only used when using Qt::UniqueConnection
|
|
|
|
\a slotObj the slot object
|
|
|
|
*/
|
|
|
|
void QTimer::singleShotImpl(int msec, Qt::TimerType timerType,
|
|
|
|
const QObject *receiver,
|
|
|
|
QtPrivate::QSlotObjectBase *slotObj)
|
|
|
|
{
|
|
|
|
new QSingleShotTimer(msec, timerType, receiver, slotObj);
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
/*!
|
|
|
|
\reentrant
|
|
|
|
This static function calls a slot after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
2012-05-11 00:38:45 +00:00
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
2011-04-27 10:05:43 +00:00
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
Example:
|
2012-03-20 18:37:07 +00:00
|
|
|
\snippet code/src_corelib_kernel_qtimer.cpp 0
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
This sample program automatically terminates after 10 minutes
|
|
|
|
(600,000 milliseconds).
|
|
|
|
|
|
|
|
The \a receiver is the receiving object and the \a member is the
|
|
|
|
slot. The time interval is \a msec milliseconds.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2012-09-13 18:23:10 +00:00
|
|
|
void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
|
2011-12-21 10:32:43 +00:00
|
|
|
{
|
2011-12-21 10:33:07 +00:00
|
|
|
// coarse timers are worst in their first firing
|
|
|
|
// so we prefer a high precision timer for something that happens only once
|
|
|
|
// unless the timeout is too big, in which case we go for coarse anyway
|
|
|
|
singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, receiver, member);
|
2011-12-21 10:32:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*! \overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls a slot after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
2012-05-11 00:38:45 +00:00
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
2011-12-21 10:32:43 +00:00
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The \a receiver is the receiving object and the \a member is the slot. The
|
|
|
|
time interval is \a msec milliseconds. The \a timerType affects the
|
|
|
|
accuracy of the timer.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
2012-09-13 18:23:10 +00:00
|
|
|
void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2014-09-18 09:54:46 +00:00
|
|
|
if (Q_UNLIKELY(msec < 0)) {
|
|
|
|
qWarning("QTimer::singleShot: Timers cannot have negative timeouts");
|
|
|
|
return;
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
if (receiver && member) {
|
|
|
|
if (msec == 0) {
|
|
|
|
// special code shortpath for 0-timers
|
|
|
|
const char* bracketPosition = strchr(member, '(');
|
2012-04-22 21:11:07 +00:00
|
|
|
if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
|
2011-04-27 10:05:43 +00:00
|
|
|
qWarning("QTimer::singleShot: Invalid slot specification");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name
|
2012-09-13 18:23:10 +00:00
|
|
|
QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.constData(), Qt::QueuedConnection);
|
2011-04-27 10:05:43 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-12-21 10:32:43 +00:00
|
|
|
(void) new QSingleShotTimer(msec, timerType, receiver, member);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-03 11:30:05 +00:00
|
|
|
/*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, const QObject *receiver, PointerToMemberFunction method)
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
\since 5.4
|
|
|
|
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls a member function of a QObject after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The \a receiver is the receiving object and the \a method is the member function. The
|
|
|
|
time interval is \a msec milliseconds.
|
|
|
|
|
|
|
|
If \a receiver is destroyed before the interval occurs, the method will not be called.
|
|
|
|
The function will be run in the thread of \a receiver. The receiver's thread must have
|
|
|
|
a running Qt event loop.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2018-01-03 11:30:05 +00:00
|
|
|
/*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method)
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
\since 5.4
|
|
|
|
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls a member function of a QObject after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The \a receiver is the receiving object and the \a method is the member function. The
|
|
|
|
time interval is \a msec milliseconds. The \a timerType affects the
|
|
|
|
accuracy of the timer.
|
|
|
|
|
|
|
|
If \a receiver is destroyed before the interval occurs, the method will not be called.
|
|
|
|
The function will be run in the thread of \a receiver. The receiver's thread must have
|
|
|
|
a running Qt event loop.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2018-01-03 11:30:05 +00:00
|
|
|
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Functor functor)
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
\since 5.4
|
|
|
|
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls \a functor after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The time interval is \a msec milliseconds.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2018-01-03 11:30:05 +00:00
|
|
|
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, Functor functor)
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
\since 5.4
|
|
|
|
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls \a functor after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The time interval is \a msec milliseconds. The \a timerType affects the
|
|
|
|
accuracy of the timer.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2018-01-03 11:30:05 +00:00
|
|
|
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, const QObject *context, Functor functor)
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
\since 5.4
|
|
|
|
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls \a functor after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The time interval is \a msec milliseconds.
|
|
|
|
|
|
|
|
If \a context is destroyed before the interval occurs, the method will not be called.
|
|
|
|
The function will be run in the thread of \a context. The context's thread must have
|
|
|
|
a running Qt event loop.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2018-01-03 11:30:05 +00:00
|
|
|
/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor)
|
2013-09-21 19:01:58 +00:00
|
|
|
|
|
|
|
\since 5.4
|
|
|
|
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
This static function calls \a functor after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The time interval is \a msec milliseconds. The \a timerType affects the
|
|
|
|
accuracy of the timer.
|
|
|
|
|
|
|
|
If \a context is destroyed before the interval occurs, the method will not be called.
|
|
|
|
The function will be run in the thread of \a context. The context's thread must have
|
|
|
|
a running Qt event loop.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
2016-05-30 19:10:08 +00:00
|
|
|
/*!
|
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using
duration_cast to coerce the duration into a milliseconds, we
violate a principal design rule of <chrono>, namely that non-
narrowing conversions are implicit, but narrowing conversions
need duration_cast. By accepting any duration, we allow non-
sensical code such as
QTimer::singleShot(10us, ...)
to compile, which is misleading, since it's actually a zero-
timeout timer.
Overloading a non-template with a template also has adverse
effects: it breaks qOverload().
Fix by replacing the function templates with functions that
just take std::chrono::milliseconds. This way, benign code
such as
QTimer::singleShot(10s, ...)
QTimer::singleShot(10min, ...)
QTimer::singleShot(1h, ...)
work as expected, but attempts to use sub-millisecond
resolution fails to compile / needs an explicit user-
provided duration_cast.
To allow future extension to more precise timers, forcibly
inline the functions, so they don't partake in the ABI of the
class and we can later support sub-millisecond resolution by
simply taking micro- or nano- instead of milliseconds.
Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2016-10-17 11:00:04 +00:00
|
|
|
\fn void QTimer::singleShot(std::chrono::milliseconds msec, const QObject *receiver, const char *member)
|
2016-05-30 19:10:08 +00:00
|
|
|
\since 5.8
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
|
|
|
|
This static function calls a slot after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The \a receiver is the receiving object and the \a member is the slot. The
|
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using
duration_cast to coerce the duration into a milliseconds, we
violate a principal design rule of <chrono>, namely that non-
narrowing conversions are implicit, but narrowing conversions
need duration_cast. By accepting any duration, we allow non-
sensical code such as
QTimer::singleShot(10us, ...)
to compile, which is misleading, since it's actually a zero-
timeout timer.
Overloading a non-template with a template also has adverse
effects: it breaks qOverload().
Fix by replacing the function templates with functions that
just take std::chrono::milliseconds. This way, benign code
such as
QTimer::singleShot(10s, ...)
QTimer::singleShot(10min, ...)
QTimer::singleShot(1h, ...)
work as expected, but attempts to use sub-millisecond
resolution fails to compile / needs an explicit user-
provided duration_cast.
To allow future extension to more precise timers, forcibly
inline the functions, so they don't partake in the ABI of the
class and we can later support sub-millisecond resolution by
simply taking micro- or nano- instead of milliseconds.
Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2016-10-17 11:00:04 +00:00
|
|
|
time interval is given in the duration object \a msec.
|
2016-05-30 19:10:08 +00:00
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using
duration_cast to coerce the duration into a milliseconds, we
violate a principal design rule of <chrono>, namely that non-
narrowing conversions are implicit, but narrowing conversions
need duration_cast. By accepting any duration, we allow non-
sensical code such as
QTimer::singleShot(10us, ...)
to compile, which is misleading, since it's actually a zero-
timeout timer.
Overloading a non-template with a template also has adverse
effects: it breaks qOverload().
Fix by replacing the function templates with functions that
just take std::chrono::milliseconds. This way, benign code
such as
QTimer::singleShot(10s, ...)
QTimer::singleShot(10min, ...)
QTimer::singleShot(1h, ...)
work as expected, but attempts to use sub-millisecond
resolution fails to compile / needs an explicit user-
provided duration_cast.
To allow future extension to more precise timers, forcibly
inline the functions, so they don't partake in the ABI of the
class and we can later support sub-millisecond resolution by
simply taking micro- or nano- instead of milliseconds.
Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2016-10-17 11:00:04 +00:00
|
|
|
\fn void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
|
2016-05-30 19:10:08 +00:00
|
|
|
\since 5.8
|
|
|
|
\overload
|
|
|
|
\reentrant
|
|
|
|
|
|
|
|
This static function calls a slot after a given time interval.
|
|
|
|
|
|
|
|
It is very convenient to use this function because you do not need
|
|
|
|
to bother with a \l{QObject::timerEvent()}{timerEvent} or
|
|
|
|
create a local QTimer object.
|
|
|
|
|
|
|
|
The \a receiver is the receiving object and the \a member is the slot. The
|
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using
duration_cast to coerce the duration into a milliseconds, we
violate a principal design rule of <chrono>, namely that non-
narrowing conversions are implicit, but narrowing conversions
need duration_cast. By accepting any duration, we allow non-
sensical code such as
QTimer::singleShot(10us, ...)
to compile, which is misleading, since it's actually a zero-
timeout timer.
Overloading a non-template with a template also has adverse
effects: it breaks qOverload().
Fix by replacing the function templates with functions that
just take std::chrono::milliseconds. This way, benign code
such as
QTimer::singleShot(10s, ...)
QTimer::singleShot(10min, ...)
QTimer::singleShot(1h, ...)
work as expected, but attempts to use sub-millisecond
resolution fails to compile / needs an explicit user-
provided duration_cast.
To allow future extension to more precise timers, forcibly
inline the functions, so they don't partake in the ABI of the
class and we can later support sub-millisecond resolution by
simply taking micro- or nano- instead of milliseconds.
Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2016-10-17 11:00:04 +00:00
|
|
|
time interval is given in the duration object \a msec. The \a timerType affects the
|
2016-05-30 19:10:08 +00:00
|
|
|
accuracy of the timer.
|
|
|
|
|
|
|
|
\sa start()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using
duration_cast to coerce the duration into a milliseconds, we
violate a principal design rule of <chrono>, namely that non-
narrowing conversions are implicit, but narrowing conversions
need duration_cast. By accepting any duration, we allow non-
sensical code such as
QTimer::singleShot(10us, ...)
to compile, which is misleading, since it's actually a zero-
timeout timer.
Overloading a non-template with a template also has adverse
effects: it breaks qOverload().
Fix by replacing the function templates with functions that
just take std::chrono::milliseconds. This way, benign code
such as
QTimer::singleShot(10s, ...)
QTimer::singleShot(10min, ...)
QTimer::singleShot(1h, ...)
work as expected, but attempts to use sub-millisecond
resolution fails to compile / needs an explicit user-
provided duration_cast.
To allow future extension to more precise timers, forcibly
inline the functions, so they don't partake in the ABI of the
class and we can later support sub-millisecond resolution by
simply taking micro- or nano- instead of milliseconds.
Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2016-10-17 11:00:04 +00:00
|
|
|
\fn void QTimer::start(std::chrono::milliseconds msec)
|
2016-05-30 19:10:08 +00:00
|
|
|
\since 5.8
|
|
|
|
\overload
|
|
|
|
|
QTimer: don't circumvent <chrono> safety net
By templating on the <chrono> types and unconditionally using
duration_cast to coerce the duration into a milliseconds, we
violate a principal design rule of <chrono>, namely that non-
narrowing conversions are implicit, but narrowing conversions
need duration_cast. By accepting any duration, we allow non-
sensical code such as
QTimer::singleShot(10us, ...)
to compile, which is misleading, since it's actually a zero-
timeout timer.
Overloading a non-template with a template also has adverse
effects: it breaks qOverload().
Fix by replacing the function templates with functions that
just take std::chrono::milliseconds. This way, benign code
such as
QTimer::singleShot(10s, ...)
QTimer::singleShot(10min, ...)
QTimer::singleShot(1h, ...)
work as expected, but attempts to use sub-millisecond
resolution fails to compile / needs an explicit user-
provided duration_cast.
To allow future extension to more precise timers, forcibly
inline the functions, so they don't partake in the ABI of the
class and we can later support sub-millisecond resolution by
simply taking micro- or nano- instead of milliseconds.
Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2016-10-17 11:00:04 +00:00
|
|
|
Starts or restarts the timer with a timeout of duration \a msec milliseconds.
|
2016-05-30 19:10:08 +00:00
|
|
|
|
|
|
|
If the timer is already running, it will be
|
|
|
|
\l{QTimer::stop()}{stopped} and restarted.
|
|
|
|
|
|
|
|
If \l singleShot is true, the timer will be activated only once.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn std::chrono::milliseconds QTimer::intervalAsDuration() const
|
|
|
|
\since 5.8
|
|
|
|
|
|
|
|
Returns the interval of this timer as a \c std::chrono::milliseconds object.
|
|
|
|
|
|
|
|
\sa interval
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn std::chrono::milliseconds QTimer::remainingTimeAsDuration() const
|
|
|
|
\since 5.8
|
|
|
|
|
|
|
|
Returns the time remaining in this timer object as a \c
|
|
|
|
std::chrono::milliseconds object. If this timer is due or overdue, the
|
|
|
|
returned value is \c std::chrono::milliseconds::zero(). If the remaining
|
|
|
|
time could not be found or the timer is not active, this function returns a
|
|
|
|
negative duration.
|
|
|
|
|
|
|
|
\sa remainingTime()
|
|
|
|
*/
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
/*!
|
|
|
|
\property QTimer::singleShot
|
|
|
|
\brief whether the timer is a single-shot timer
|
|
|
|
|
|
|
|
A single-shot timer fires only once, non-single-shot timers fire
|
|
|
|
every \l interval milliseconds.
|
|
|
|
|
2016-09-29 08:42:20 +00:00
|
|
|
The default value for this property is \c false.
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
\sa interval, singleShot()
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\property QTimer::interval
|
|
|
|
\brief the timeout interval in milliseconds
|
|
|
|
|
|
|
|
The default value for this property is 0. A QTimer with a timeout
|
|
|
|
interval of 0 will time out as soon as all the events in the window
|
|
|
|
system's event queue have been processed.
|
|
|
|
|
|
|
|
Setting the interval of an active timer changes its timerId().
|
|
|
|
|
|
|
|
\sa singleShot
|
|
|
|
*/
|
|
|
|
void QTimer::setInterval(int msec)
|
|
|
|
{
|
|
|
|
inter = msec;
|
|
|
|
if (id != INV_TIMER) { // create new timer
|
|
|
|
QObject::killTimer(id); // restart timer
|
2011-12-21 10:32:43 +00:00
|
|
|
id = QObject::startTimer(msec, Qt::TimerType(type));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add a remainingTime() method to the public interface of the QTimer class
It is an extension coming from the use case when you, for instance, need to
implement a countdown timer in client codes, and manually maintain a dedicated
variable for counting down with the help of yet another Timer. There might be
other use cases as well. The returned value is meant to be in milliseconds, as
the method documentation says, since it is reasonable, and consistent with the
rest (ie. the interval accessor).
The elapsed time is already being tracked inside the event dispatcher, thus the
effort is only exposing that for all platforms supported according to the
desired timer identifier, and propagating up to the QTimer public API. It is
done by using the QTimerInfoList class in the glib and unix dispatchers, and the
WinTimeInfo struct for the windows dispatcher.
It might be a good idea to to establish a QWinTimerInfo
(qtimerinfo_win{_p.h,cpp}) in the future for resembling the interface for
windows with the glib/unix management so that it would be consistent. That would
mean abstracting out a base class (~interface) for the timer info classes.
Something like that QAbstractTimerInfo.
Test: Build test only on (Arch)Linux, Windows and Mac. I have also run the unit
tests and they passed as well.
Change-Id: Ie37b3aff909313ebc92e511e27d029abb070f110
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
2012-02-23 05:41:30 +00:00
|
|
|
/*!
|
|
|
|
\property QTimer::remainingTime
|
2013-02-02 17:23:29 +00:00
|
|
|
\since 5.0
|
Add a remainingTime() method to the public interface of the QTimer class
It is an extension coming from the use case when you, for instance, need to
implement a countdown timer in client codes, and manually maintain a dedicated
variable for counting down with the help of yet another Timer. There might be
other use cases as well. The returned value is meant to be in milliseconds, as
the method documentation says, since it is reasonable, and consistent with the
rest (ie. the interval accessor).
The elapsed time is already being tracked inside the event dispatcher, thus the
effort is only exposing that for all platforms supported according to the
desired timer identifier, and propagating up to the QTimer public API. It is
done by using the QTimerInfoList class in the glib and unix dispatchers, and the
WinTimeInfo struct for the windows dispatcher.
It might be a good idea to to establish a QWinTimerInfo
(qtimerinfo_win{_p.h,cpp}) in the future for resembling the interface for
windows with the glib/unix management so that it would be consistent. That would
mean abstracting out a base class (~interface) for the timer info classes.
Something like that QAbstractTimerInfo.
Test: Build test only on (Arch)Linux, Windows and Mac. I have also run the unit
tests and they passed as well.
Change-Id: Ie37b3aff909313ebc92e511e27d029abb070f110
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
2012-02-23 05:41:30 +00:00
|
|
|
\brief the remaining time in milliseconds
|
|
|
|
|
|
|
|
Returns the timer's remaining value in milliseconds left until the timeout.
|
|
|
|
If the timer is inactive, the returned value will be -1. If the timer is
|
|
|
|
overdue, the returned value will be 0.
|
|
|
|
|
|
|
|
\sa interval
|
|
|
|
*/
|
|
|
|
int QTimer::remainingTime() const
|
|
|
|
{
|
|
|
|
if (id != INV_TIMER) {
|
|
|
|
return QAbstractEventDispatcher::instance()->remainingTime(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-12-21 10:32:43 +00:00
|
|
|
/*!
|
|
|
|
\property QTimer::timerType
|
|
|
|
\brief controls the accuracy of the timer
|
|
|
|
|
|
|
|
The default value for this property is \c Qt::CoarseTimer.
|
|
|
|
|
|
|
|
\sa Qt::TimerType
|
|
|
|
*/
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QT_END_NAMESPACE
|
2012-09-03 14:56:48 +00:00
|
|
|
|
|
|
|
#include "qtimer.moc"
|
QtCore: include mocs
Compilation and link times in CPU seconds with GCC 7, using precompiled
headers (not including moc, rcc, uic, etc. steps or headersclean):
Before After
Debug -O0 198,1 180,3
Debug -Og 240,7 229,2
Release -O3 267,1 249,2
Release LTO 239,4 229,8
QtCore required a little manual adjusting because some files are
bootstrapped into moc itself and into qmake.
Change-Id: I84e363d735b443cb9beefffd14b8b57c10e7da36
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
2017-04-25 17:53:40 +00:00
|
|
|
#include "moc_qtimer.cpp"
|