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>
This commit is contained in:
parent
863c688749
commit
a6d1456458
@ -570,6 +570,48 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
|
||||
\sa start()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\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
|
||||
|
@ -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:
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user