diff options
author | Sergio Martins <iamsergio@gmail.com> | 2018-03-05 22:54:57 +0000 |
---|---|---|
committer | Sérgio Martins <sergio.martins@kdab.com> | 2018-03-25 21:17:20 +0000 |
commit | a6d1456458b6e19c850adadb1a81c4a9acbdbe92 (patch) | |
tree | a4d52f18929ee0d04ffd19b48afb578538dcf89f | |
parent | 863c6887495c0bd9ee3a85aa7cd2d997cdc5c93c (diff) |
Add QTimer::connectTo(), a shorthand way of connecting to timeout()
There are a couple of Qt classes where you almost always use the
same signal, for example QTimer::timeout, QPushButton::clicked,
and QAction::triggered.
Simply doing timer.connectTo([]{}) is much more convenient, less
tedious and even fun.
Not overloading connect() as it would be confusing to see the
receiver as first argument.
And not naming it onTimeout, as that's a popular way of doing it in
other frameworks. People would assume you could use on* with any signal.
If we ever have on* it should be all or nothing.
[ChangeLog][QtCore] Added QTimer::connectTo(), a shorthand way of
connecting to the timeout() signal.
Change-Id: Ida57e5442b13d50972ed585c3ea7be07e3d8e8d2
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
-rw-r--r-- | src/corelib/kernel/qtimer.cpp | 42 | ||||
-rw-r--r-- | src/corelib/kernel/qtimer.h | 13 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp | 27 |
3 files changed, 82 insertions, 0 deletions
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index c3504943c4..802c8d72f6 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -571,6 +571,48 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! + \fn template<typename Functor> QMetaObject::Connection connectTo(Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection) + \since 5.12 + \overload + + Creates a connection from the timeout() signal to \a functor, and returns a + handle to the connection. + + This method is provided for convenience. + It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, functor, connectionType)}. + + \sa QObject::connect(), timeout() +*/ + +/*! + \fn template<typename Functor> QMetaObject::Connection connectTo(QObject *context, Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection) + \since 5.12 + \overload connectTo() + + Creates a connection from the timeout() signal to \a functor 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, functor, connectionType)}. + + \sa QObject::connect(), timeout() +*/ + +/*! + \fn template<typename PointerToMemberFunction> QMetaObject::Connection connectTo(QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType connectionType = Qt::AutoConnection) + \since 5.12 + \overload connectTo() + + Creates a connection from the timeout() signal to the \a method 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, method, connectionType)}. + + \sa QObject::connect(), timeout() +*/ + +/*! \fn void QTimer::start(std::chrono::milliseconds msec) \since 5.8 \overload diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index e6db586aa0..7825bb0798 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -96,6 +96,12 @@ public: static void singleShot(int msec, const QObject *context, Functor functor); template<typename Functor, int> static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor); + template <typename Functor> + QMetaObject::Connection connectTo(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template <typename Functor> + QMetaObject::Connection connectTo(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template <typename PointerToMemberFunction> + QMetaObject::Connection connectTo(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); #else // singleShot to a QObject slot template <typename Duration, typename Func1> @@ -152,6 +158,13 @@ public: new QtPrivate::QFunctorSlotObject<Func1, 0, typename QtPrivate::List_Left<void, 0>::Value, void>(std::move(slot))); } + + template <typename ... Args> + QMetaObject::Connection connectTo(Args && ...args) + { + return QObject::connect(this, &QTimer::timeout, std::forward<Args>(args)... ); + } + #endif public Q_SLOTS: diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index 2c6d9ea7c0..2d34aceab8 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -75,6 +75,7 @@ private slots: void dontBlockEvents(); void postedEventsShouldNotStarveTimers(); + void connectTo(); }; class TimerHelper : public QObject @@ -1020,5 +1021,31 @@ void tst_QTimer::crossThreadSingleShotToFunctor() delete o; } +void tst_QTimer::connectTo() +{ + QTimer timer; + TimerHelper timerHelper; + timer.setInterval(0); + timer.start(); + + auto context = new QObject(); + + int count = 0; + timer.connectTo([&count] { count++; }); + QMetaObject::Connection connection = timer.connectTo(context, [&count] { count++; }); + timer.connectTo(&timerHelper, &TimerHelper::timeout); + timer.connectTo(&timer, &QTimer::stop); + + + QTest::qWait(100); + QCOMPARE(count, 2); + QCOMPARE(timerHelper.count, 1); + + // Test that connection is bound to context lifetime + QVERIFY(connection); + delete context; + QVERIFY(!connection); +} + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" |