Usage of QTimer::singleShot(int msec, Func1 slot)?



  • Hi,

    I recently stumbled upon this particular variant of QTimer::singleShot. What is this meant to do? I stepped through the code and it ends up calling QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member) with receiver being 0 and it does nothing. This is Qt 5.4.1 by the way.


  • Moderators

    Hi,

    @Thuan_Firelight said:

    I stepped through the code and it ends up calling QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)

    That sounds odd to me. How are you ensuring that you are using this overload?

    Func1 is a function pointer. You can use this overload of QTimer::singleShot() to call a standalone function or a lambda expression:

    void standaloneFunc()
    {
        qDebug() << "Hello from standaloneFunc()";
    }
    
    int main(int argc, char **argv)
    {
        // ...
    
        QTimer::singleShot(1000, &standaloneFunc);
    
        QTimer::singleShot(2000, []{
            qDebug("Hello from lambda");
        });
    
        // ...
    }
    

    This will print "Hello from standaloneFunc()" after 1 second, and "Hello from lambda" after 2 seconds.



  • @JKSH said:

    QTimer::singleShot(1000, &standaloneFunc);

    Sorry for the late response. Just realized someone has replied to my question. In my code, I used the old syntax,

    QTimer::singleShot(0, SLOT(standaloneFunc())); 
    

    Both your code and my code goes into singleShot(int msec, Func1 slot) but seems to do different things. In my case I was really meant to call a function on a particular receiver, so passing the receiver fixed my problem. Just curious regarding the behavior. If I step through the code, it goes to:

    qtimer.h

        // singleShot to a functor or function pointer (without context)
        template <typename Func1>
        static inline void singleShot(int msec, Func1 slot)
        {
            singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, Q_NULLPTR, slot);
        }
    
    
    

    qtimer.cpp

    void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member)
    {
        if (Q_UNLIKELY(msec < 0)) {
            qWarning("QTimer::singleShot: Timers cannot have negative timeouts");
            return;
        }
        if (receiver && member) {
            if (msec == 0) {
                // special code shortpath for 0-timers
                const char* bracketPosition = strchr(member, '(');
                if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
                    qWarning("QTimer::singleShot: Invalid slot specification");
                    return;
                }
                QByteArray methodName(member+1, bracketPosition - 1 - member); // extract method name
                QMetaObject::invokeMethod(const_cast<QObject *>(receiver), methodName.constData(), Qt::QueuedConnection);
                return;
            }
            (void) new QSingleShotTimer(msec, timerType, receiver, member);
        }
    }
    

    which just bails out without a warning.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.