c++qtqt4

What does QTimer::singleShot(0, object, SLOT(obj_slot())) do?


I'm beginner learning Qt, and trying to understand a Qt provided example for download operation. In downloadmanager.cpp, a member function is the following:

void DownloadManager::append(const QUrl &url)
{
    if (downloadQueue.isEmpty())
        QTimer::singleShot(0, this, SLOT(startNextDownload()));

    downloadQueue.enqueue(url);
    ++totalCount;
}

Clarification:

I'm a beginner and in examples like:

statement1;
statement2;

I'm used to seeing statement1 running and finishing before moving on to working on statement2. But trying to learn Qt and reading the given example, I see the SLOT(startNextDownload()) being activated after downloadQueue.enqueue(url); has taken place. I am trying to understand why does this work.


Solution

  • Answer to current question title

    Every call to QTimer::singleShot(...) is executed on the event loop of the thread where it is invoked **. If invoked from the main thread, it'll be the event loop started with app.exec().

    According to the Qt-Network-Manager-Example, this function is called after the network-manager is filled with the URL's so the single-shot will be processed after the queue has been completely filled. Poorly the qt documentation isn't that clear about this topic yet, so for more information about event processing etc please look here.


    Answer for old question title

    Before I start, the timer is for having the download in an extra thread. So the GUI keeps responsive.

    The complete downloadNext() method is recursive. It will be only called once and called till the queue is empty. See this:

    void DownloadManager::append(const QStringList &urlList)
    {
        foreach (QString url, urlList)
            append(QUrl::fromEncoded(url.toLocal8Bit())); //Call for only one URL
      ...
    }
    
    void DownloadManager::append(const QUrl &url)
    {
        if (downloadQueue.isEmpty())
            //I'm only called if the queue is empty! And I will be called after the next line. Not instantly!
            QTimer::singleShot(0, this, SLOT(startNextDownload()));  
    
        downloadQueue.enqueue(url);
        ++totalCount;
    }
    

    After the queue is empty each method returns and at least the message that the download is done will be printed.

    So why does this work? Please see first chapter below.