• 16762阅读
  • 5回复

让(QTimer的)singleShot()函数也能“用上”新的connect语法 [复制链接]

上一主题 下一主题
离线roywillow
 

只看楼主 倒序阅读 楼主  发表于: 2013-03-16
之前遇到一个需要用到QTimer::singleShot()的地方,结果发现这东西不支持新的connect语法,没法用lambda函数,而如果用旧的语法来实现的话,整个代码就会变得复杂而不好维护。

于是看了一下QObject的源码,了解了一下新语法信号和槽作为参数传入的方法,自己写了一个singleShot()。

思路很简单,函数中构造一个QTimer,设置好timer的interval,连接timer的timeout()信号和传入的槽,连接timer的timeout()信号和deleteLater()槽以实现触发后自动销毁(Qt5里槽的调用顺序跟connect的顺序是一致的对吧对吧对吧?←这一点略微没底……),然后执行timer->start()。
所以说归根结底还是要自己构造个QTimer来实现,效率可能不如QTimer的那个吧……不知道有没有更好的办法呢

  1. #ifndef SINGLESHOT_H
  2. #define SINGLESHOT_H
  3. #include <QTimer>
  4. namespace QTimerExtend
  5. {
  6. template <typename Func1>
  7.     static inline void singleShot(int msec,
  8.                                   const typename QtPrivate::FunctionPointer<Func1>::Object *receiver,
  9.                                   Func1 slot)
  10.     {
  11.         QTimer *timer = new QTimer;
  12.         timer->setInterval(msec);
  13.         QObject::connect(timer, &QTimer::timeout, receiver, slot);
  14.         QObject::connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
  15.         timer->start();
  16.     }
  17.     template <typename Func1>
  18.     static inline void singleShot(int msec, Func1 slot)
  19.     {
  20.         QTimer *timer = new QTimer;
  21.         timer->setInterval(msec);
  22.         QObject::connect(timer, &QTimer::timeout, slot);
  23.         QObject::connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
  24.         timer->start();
  25.     }
  26. }
  27. #endif // SINGLESHOT_H


经过以下代码的测试没问题
  1. //......
  2. QTimerExtend::singleShot(0, this, &Widget::testSlot);
  3. QTimerExtend::singleShot(0, [] {qDebug("lambda actived.");});
  4. QTimerExtend::singleShot(3000, this, &Widget::testSlot);
  5. QTimerExtend::singleShot(4000, [] {qDebug("lambda actived.");});
  6. //......
  7. void Widget::testSlot()
  8. {
  9.     qDebug("slot actived.");
  10. }
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线mewjerry
只看该作者 1楼 发表于: 2013-03-16
ROY大神厉害-。-虽然说好像用std的bind也可以的样子
离线roywillow

只看该作者 2楼 发表于: 2013-03-16
回 1楼(mewjerry) 的帖子
how?
看了一下std::bind的介绍,没找到突破口,并且介绍新语法的一篇wiki也提到了
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线woniu600

只看该作者 3楼 发表于: 2014-12-15
回 roywillow 的帖子
roywillow:how?
看了一下std::bind的介绍,没找到突破口,并且介绍新语法的一篇wiki也提到了 (2013-03-16 18:02) 

有找到bind 的 QTimer + lambda 的方法吗?

以为Qt5.4能修改会这个 bug 改掉呢.结果没改
离线roywillow

只看该作者 4楼 发表于: 2014-12-15
回 woniu600 的帖子
woniu600:有找到bind 的 QTimer + lambda 的方法吗?
以为Qt5.4能修改会这个 bug 改掉呢.结果没改
 (2014-12-15 15:40) 

std的东西不怎么会用,抱歉
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线lzh280

只看该作者 5楼 发表于: 2014-12-16
试用过 Qt5.4 支持新的 connect 语法和 lambda 表达式。
快速回复
限100 字节
 
上一个 下一个