之前遇到一个需要用到
QTimer::singleShot()的地方,结果发现这东西不支持新的connect语法,没法用lambda函数,而如果用旧的语法来实现的话,整个代码就会变得复杂而不好维护。
于是看了一下
QObject的源码,了解了一下新语法信号和槽作为
参数传入的方法,自己写了一个singleShot()。
思路很简单,函数中构造一个QTimer,设置好timer的interval,连接timer的timeout()信号和传入的槽,连接timer的timeout()信号和deleteLater()槽以实现触发后自动销毁(Qt5里槽的调用顺序跟connect的顺序是一致的对吧对吧对吧?←这一点略微没底……),然后执行timer->start()。
所以说归根结底还是要自己构造个QTimer来实现,效率可能不如QTimer的那个吧……不知道有
没有更好的办法呢
- #ifndef SINGLESHOT_H
- #define SINGLESHOT_H
- #include <QTimer>
- namespace QTimerExtend
- {
- template <typename Func1>
- static inline void singleShot(int msec,
- const typename QtPrivate::FunctionPointer<Func1>::Object *receiver,
- Func1 slot)
- {
- QTimer *timer = new QTimer;
- timer->setInterval(msec);
- QObject::connect(timer, &QTimer::timeout, receiver, slot);
- QObject::connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
- timer->start();
- }
- template <typename Func1>
- static inline void singleShot(int msec, Func1 slot)
- {
- QTimer *timer = new QTimer;
- timer->setInterval(msec);
- QObject::connect(timer, &QTimer::timeout, slot);
- QObject::connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
- timer->start();
- }
- }
- #endif // SINGLESHOT_H
经过以下代码的测试没
问题:
- //......
- QTimerExtend::singleShot(0, this, &Widget::testSlot);
- QTimerExtend::singleShot(0, [] {qDebug("lambda actived.");});
- QTimerExtend::singleShot(3000, this, &Widget::testSlot);
- QTimerExtend::singleShot(4000, [] {qDebug("lambda actived.");});
- //......
- void Widget::testSlot()
- {
- qDebug("slot actived.");
- }