查看完整版本: [-- 让(QTimer的)singleShot()函数也能“用上”新的connect语法 --]

QTCN开发网 -> Qt代码秀 -> 让(QTimer的)singleShot()函数也能“用上”新的connect语法 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

roywillow 2013-03-16 11:45

让(QTimer的)singleShot()函数也能“用上”新的connect语法

之前遇到一个需要用到QTimer::singleShot()的地方,结果发现这东西不支持新的connect语法,没法用lambda函数,而如果用旧的语法来实现的话,整个代码就会变得复杂而不好维护。

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

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

  1. #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


经过以下代码的测试没问题:
  1. //......
    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.");
    }

mewjerry 2013-03-16 16:11
ROY大神厉害-。-虽然说好像用std的bind也可以的样子

roywillow 2013-03-16 18:02
how?
看了一下std::bind的介绍,没找到突破口,并且介绍新语法的一篇wiki也提到了

woniu600 2014-12-15 15:40
roywillow:how?
看了一下std::bind的介绍,没找到突破口,并且介绍新语法的一篇wiki也提到了 (2013-03-16 18:02) 

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

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

roywillow 2014-12-15 19:36
woniu600:有找到bind 的 QTimer + lambda 的方法吗?
以为Qt5.4能修改会这个 bug 改掉呢.结果没改
 (2014-12-15 15:40) 

std的东西不怎么会用,抱歉

lzh280 2014-12-16 23:05
试用过 Qt5.4 支持新的 connect 语法和 lambda 表达式。


查看完整版本: [-- 让(QTimer的)singleShot()函数也能“用上”新的connect语法 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled