summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qtimer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qtimer.cpp')
-rw-r--r--src/corelib/kernel/qtimer.cpp466
1 files changed, 172 insertions, 294 deletions
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 6e3d34214f..cc46c1433b 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -1,63 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** 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.
-**
-** 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.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtimer.h"
+#include "qtimer_p.h"
+#include "qsingleshottimer_p.h"
+
#include "qabstracteventdispatcher.h"
#include "qcoreapplication.h"
+#include "qcoreapplication_p.h"
+#include "qdeadlinetimer.h"
+#include "qmetaobject_p.h"
#include "qobject_p.h"
+#include "qproperty_p.h"
#include "qthread.h"
-#include "qcoreapplication_p.h"
-
-QT_BEGIN_NAMESPACE
-static constexpr int INV_TIMER = -1; // invalid timer id
+using namespace std::chrono_literals;
-class QTimerPrivate : public QObjectPrivate
-{
-public:
- int id = INV_TIMER;
- int inter = 0;
- bool single = false;
- bool nulltimer = false;
- Qt::TimerType type = Qt::CoarseTimer;
-};
+QT_BEGIN_NAMESPACE
/*!
\class QTimer
@@ -114,6 +74,13 @@ public:
more and more platforms, we expect that zero-millisecond
QTimer objects will gradually be replaced by \l{QThread}s.
+ \note Since Qt 6.7 this class is superseded by \l{QChronoTimer}.
+ The maximum interval QTimer supports is limited by the number of
+ milliseconds that would fit in an \c int (which is around 24 days);
+ whereas QChronoTimer stores its interval as \c std::chrono::nanoseconds
+ (which raises that limit to around 292 million years), that is, there is
+ less chance of integer overflow with QChronoTimer.
+
\section1 Accuracy and Timer Resolution
The accuracy of timers depends on the underlying operating system
@@ -150,7 +117,7 @@ public:
used; Qt tries to work around these limitations.
\sa QBasicTimer, QTimerEvent, QObject::timerEvent(), Timers,
- {Analog Clock Example}, {Wiggly Example}
+ {Analog Clock}
*/
/*!
@@ -158,8 +125,9 @@ public:
*/
QTimer::QTimer(QObject *parent)
- : QObject(*new QTimerPrivate, parent)
+ : QObject(*new QTimerPrivate(this), parent)
{
+ Q_ASSERT(d_func()->isQTimer);
}
@@ -169,7 +137,7 @@ QTimer::QTimer(QObject *parent)
QTimer::~QTimer()
{
- if (d_func()->id != INV_TIMER) // stop running timer
+ if (d_func()->isActive()) // stop running timer
stop();
}
@@ -198,7 +166,12 @@ QTimer::~QTimer()
*/
bool QTimer::isActive() const
{
- return d_func()->id >= 0;
+ return d_func()->isActiveData.value();
+}
+
+QBindable<bool> QTimer::bindableActive()
+{
+ return QBindable<bool>(&d_func()->isActiveData);
}
/*!
@@ -209,9 +182,21 @@ bool QTimer::isActive() const
*/
int QTimer::timerId() const
{
- return d_func()->id;
+ auto v = qToUnderlying(id());
+ return v == 0 ? -1 : v;
}
+/*!
+ \since 6.8
+ Returns a Qt::TimerId representing the timer ID if the timer is running;
+ otherwise returns \c Qt::TimerId::Invalid.
+
+ \sa Qt::TimerId
+*/
+Qt::TimerId QTimer::id() const
+{
+ return d_func()->id;
+}
/*! \overload start()
@@ -225,10 +210,14 @@ int QTimer::timerId() const
void QTimer::start()
{
Q_D(QTimer);
- if (d->id != INV_TIMER) // stop running timer
+ if (d->isActive()) // stop running timer
stop();
- d->nulltimer = (!d->inter && d->single);
- d->id = QObject::startTimer(d->inter, d->type);
+
+ const auto newId = Qt::TimerId{QObject::startTimer(d->inter * 1ms, d->type)};
+ if (newId > Qt::TimerId::Invalid) {
+ d->id = newId;
+ d->isActiveData.notify();
+ }
}
/*!
@@ -238,14 +227,33 @@ void QTimer::start()
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.
+ If \l singleShot is true, the timer will be activated only once. This is
+ equivalent to:
+
+ \code
+ timer.setInterval(msec);
+ timer.start();
+ \endcode
+ \note Keeping the event loop busy with a zero-timer is bound to
+ cause trouble and highly erratic behavior of the UI.
*/
void QTimer::start(int msec)
{
+ start(msec * 1ms);
+}
+
+void QTimer::start(std::chrono::milliseconds interval)
+{
Q_D(QTimer);
- d->inter = msec;
+ // This could be narrowing as the interval is stored in an `int` QProperty,
+ // and the type can't be changed in Qt6.
+ const int msec = interval.count();
+ const bool intervalChanged = msec != d->inter;
+ d->inter.setValue(msec);
start();
+ if (intervalChanged)
+ d->inter.notify();
}
@@ -259,9 +267,10 @@ void QTimer::start(int msec)
void QTimer::stop()
{
Q_D(QTimer);
- if (d->id != INV_TIMER) {
+ if (d->isActive()) {
QObject::killTimer(d->id);
- d->id = INV_TIMER;
+ d->id = Qt::TimerId::Invalid;
+ d->isActiveData.notify();
}
}
@@ -272,84 +281,13 @@ void QTimer::stop()
void QTimer::timerEvent(QTimerEvent *e)
{
Q_D(QTimer);
- if (e->timerId() == d->id) {
+ if (Qt::TimerId{e->timerId()} == d->id) {
if (d->single)
stop();
emit timeout(QPrivateSignal());
}
}
-class QSingleShotTimer : public QObject
-{
- Q_OBJECT
- int timerId;
- bool hasValidReceiver;
- QPointer<const QObject> receiver;
- QtPrivate::QSlotObjectBase *slotObj;
-public:
- ~QSingleShotTimer();
- QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char * m);
- QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj);
-
-Q_SIGNALS:
- void timeout();
-protected:
- void timerEvent(QTimerEvent *) override;
-};
-
-QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char *member)
- : QObject(QAbstractEventDispatcher::instance()), hasValidReceiver(true), slotObj(nullptr)
-{
- 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)
-{
- timerId = startTimer(msec, timerType);
- if (r && thread() != r->thread()) {
- // Avoid leaking the QSingleShotTimer instance in case the application exits before the timer fires
- connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
- setParent(nullptr);
- moveToThread(r->thread());
- }
-}
-
-QSingleShotTimer::~QSingleShotTimer()
-{
- if (timerId > 0)
- killTimer(timerId);
- if (slotObj)
- slotObj->destroyIfLastRef();
-}
-
-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;
-
- 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] = { nullptr };
- slotObj->call(const_cast<QObject*>(receiver.data()), args);
- }
- } else {
- emit timeout();
- }
-
- // 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);
-}
-
/*!
\internal
@@ -359,14 +297,13 @@ void QSingleShotTimer::timerEvent(QTimerEvent *)
\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,
+*/
+void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerType,
const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj)
{
- if (msec == 0) {
+ if (msec == 0ms) {
bool deleteReceiver = false;
// Optimize: set a receiver context when none is given, such that we can use
// QMetaObject::invokeMethod which is more efficient than going through a timer.
@@ -385,8 +322,10 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType,
deleteReceiver = true;
}
+ auto h = QtPrivate::invokeMethodHelper({});
QMetaObject::invokeMethodImpl(const_cast<QObject *>(receiver), slotObj,
- Qt::QueuedConnection, nullptr);
+ Qt::QueuedConnection, h.parameterCount(), h.parameters.data(), h.typeNames.data(),
+ h.metaTypes.data());
if (deleteReceiver)
const_cast<QObject *>(receiver)->deleteLater();
@@ -397,7 +336,9 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType,
}
/*!
+ \fn void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
\reentrant
+ \deprecated [6.8] Use the chrono overloads.
This static function calls a slot after a given time interval.
It is very convenient to use this function because you do not need
@@ -416,16 +357,11 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType,
\sa start()
*/
-void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
-{
- // 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);
-}
-
-/*! \overload
+/*!
+ \fn void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
+ \overload
\reentrant
+ \deprecated [6.8] Use the chrono overloads.
This static function calls a slot after a given time interval.
It is very convenient to use this function because you do not need
@@ -438,147 +374,54 @@ void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
\sa start()
*/
-void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
+
+void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType,
+ const QObject *receiver, const char *member)
{
- if (Q_UNLIKELY(msec < 0)) {
+ if (Q_UNLIKELY(msec < 0ms)) {
qWarning("QTimer::singleShot: Timers cannot have negative timeouts");
return;
}
if (receiver && member) {
- if (msec == 0) {
+ if (msec == 0ms) {
// special code shortpath for 0-timers
const char* bracketPosition = strchr(member, '(');
if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
qWarning("QTimer::singleShot: Invalid slot specification");
return;
}
- QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name
- QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.constData(), Qt::QueuedConnection);
+ const auto methodName = QByteArrayView(member + 1, // extract method name
+ bracketPosition - 1 - member).trimmed();
+ QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.toByteArray().constData(),
+ Qt::QueuedConnection);
return;
}
(void) new QSingleShotTimer(msec, timerType, receiver, member);
}
}
-/*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, const QObject *receiver, PointerToMemberFunction method)
-
+/*! \fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, const QObject *context, Functor &&functor)
+ \fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, Qt::TimerType timerType, const QObject *context, Functor &&functor)
+ \fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, Functor &&functor)
+ \fn template<typename Duration, typename Functor> void QTimer::singleShot(Duration msec, Qt::TimerType timerType, Functor &&functor)
\since 5.4
- \overload
\reentrant
- This static function calls a member function of a QObject after a given time interval.
+ This static function calls \a functor after \a msec milliseconds.
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()
-*/
-
-/*! \fn template<typename PointerToMemberFunction> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method)
-
- \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.
+ If \a context is specified, then the \a functor will be called only if the
+ \a context object has not been destroyed before the interval occurs. The functor
+ will then be run the thread of \a context. The context's thread must have a
+ running Qt event loop.
- 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 functor is a member
+ function of \a context, then the function will be called on the object.
- 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()
-*/
-
-/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Functor functor)
-
- \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()
-*/
-
-/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, Functor functor)
-
- \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()
-*/
-
-/*! \fn template<typename Functor> void QTimer::singleShot(int msec, const QObject *context, Functor functor)
-
- \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()
-*/
-
-/*! \fn template<typename Functor> void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor)
-
- \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.
+ The \a msec parameter can be an \c int or a \c std::chrono::milliseconds value.
\sa start()
*/
@@ -621,43 +464,35 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
*/
/*!
- \fn template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \fn template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(Functor &&slot)
\since 5.12
- \overload
- Creates a connection of type \a connectionType from the timeout() signal
- to \a slot, and returns a handle to the connection.
+ Creates a connection from the timer's timeout() signal to \a slot.
+ Returns a handle to the connection.
- This method is provided for convenience.
- It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, slot, connectionType)}.
+ This method is provided for convenience. It's equivalent to calling:
+ \code
+ QObject::connect(timer, &QTimer::timeout, timer, slot, Qt::DirectConnection);
+ \endcode
+
+ \note This overload is not available when \c {QT_NO_CONTEXTLESS_CONNECT} is
+ defined, instead use the callOnTimeout() overload that takes a context object.
\sa QObject::connect(), timeout()
*/
/*!
- \fn template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \fn template <typename Functor> QMetaObject::Connection QTimer::callOnTimeout(const QObject *context, Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
\since 5.12
\overload callOnTimeout()
Creates a connection from the timeout() signal to \a slot to be placed in a specific
event loop of \a context, and returns a handle to the connection.
- This method is provided for convenience. It's equivalent to calling
- \c {QObject::connect(timer, &QTimer::timeout, context, slot, connectionType)}.
-
- \sa QObject::connect(), timeout()
-*/
-
-/*!
- \fn template <typename MemberFunction> QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection)
- \since 5.12
- \overload callOnTimeout()
-
- Creates a connection from the timeout() signal to the \a slot in the \a receiver object. Returns
- a handle to the connection.
-
- This method is provided for convenience. It's equivalent to calling
- \c {QObject::connect(timer, &QTimer::timeout, receiver, slot, connectionType)}.
+ This method is provided for convenience. It's equivalent to calling:
+ \code
+ QObject::connect(timer, &QTimer::timeout, context, slot, connectionType);
+ \endcode
\sa QObject::connect(), timeout()
*/
@@ -672,7 +507,13 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
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.
+ If \l singleShot is true, the timer will be activated only once. This is
+ equivalent to:
+
+ \code
+ timer.setInterval(msec);
+ timer.start();
+ \endcode
*/
/*!
@@ -718,6 +559,11 @@ bool QTimer::isSingleShot() const
return d_func()->single;
}
+QBindable<bool> QTimer::bindableSingleShot()
+{
+ return QBindable<bool>(&d_func()->single);
+}
+
/*!
\property QTimer::interval
\brief the timeout interval in milliseconds
@@ -732,12 +578,33 @@ bool QTimer::isSingleShot() const
*/
void QTimer::setInterval(int msec)
{
+ setInterval(std::chrono::milliseconds{msec});
+}
+
+void QTimer::setInterval(std::chrono::milliseconds interval)
+{
Q_D(QTimer);
- d->inter = msec;
- if (d->id != INV_TIMER) { // create new timer
+ // This could be narrowing as the interval is stored in an `int` QProperty,
+ // and the type can't be changed in Qt6.
+ const int msec = interval.count();
+ d->inter.removeBindingUnlessInWrapper();
+ const bool intervalChanged = msec != d->inter.valueBypassingBindings();
+ d->inter.setValueBypassingBindings(msec);
+ if (d->isActive()) { // create new timer
QObject::killTimer(d->id); // restart timer
- d->id = QObject::startTimer(msec, d->type);
+ const auto newId = Qt::TimerId{QObject::startTimer(msec * 1ms, d->type)};
+ if (newId > Qt::TimerId::Invalid) {
+ // Restarted successfully. No need to update the active state.
+ d->id = newId;
+ } else {
+ // Failed to start the timer.
+ // Need to notify about active state change.
+ d->id = Qt::TimerId::Invalid;
+ d->isActiveData.notify();
+ }
}
+ if (intervalChanged)
+ d->inter.notify();
}
int QTimer::interval() const
@@ -745,6 +612,11 @@ int QTimer::interval() const
return d_func()->inter;
}
+QBindable<int> QTimer::bindableInterval()
+{
+ return QBindable<int>(&d_func()->inter);
+}
+
/*!
\property QTimer::remainingTime
\since 5.0
@@ -759,8 +631,10 @@ int QTimer::interval() const
int QTimer::remainingTime() const
{
Q_D(const QTimer);
- if (d->id != INV_TIMER) {
- return QAbstractEventDispatcher::instance()->remainingTime(d->id);
+ if (d->isActive()) {
+ using namespace std::chrono;
+ auto remaining = QAbstractEventDispatcher::instance()->remainingTime(d->id);
+ return ceil<milliseconds>(remaining).count();
}
return -1;
@@ -784,7 +658,11 @@ Qt::TimerType QTimer::timerType() const
return d_func()->type;
}
+QBindable<Qt::TimerType> QTimer::bindableTimerType()
+{
+ return QBindable<Qt::TimerType>(&d_func()->type);
+}
+
QT_END_NAMESPACE
-#include "qtimer.moc"
#include "moc_qtimer.cpp"