QTimer :: singleShot(0,object SLOT(obj_slot()))有什么作用?

Rob*_*and 5 c++ qt qt4

我是初学者,学习Qt,并试图了解Qt提供的下载操作示例。在downloadmanager.cpp中,成员函数如下:

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

    downloadQueue.enqueue(url);
    ++totalCount;
}
Run Code Online (Sandbox Code Playgroud)
  • 我感到困惑,为什么,如果downloadQueue为空,则需要startNextDownload()在添加URL之前先激活。(注意:startNextDownload()如果downloadQueue为空,则结束程序)
  • 我不确定为什么:QTimer::signleShot(x, y, z)根本没有使用过。据我所知,是一个计时器,它以0毫秒的延迟激活插槽。
  • 我无法通过查看Qt Assistant来确定singleShot是一次性设置以在给定的毫秒间隔内重复激活到插槽还是一次

澄清:

我是新手,例如:

statement1;
statement2;
Run Code Online (Sandbox Code Playgroud)

statement1在继续进行之前,我经常看到运行和完成的情况statement2。但是尝试学习Qt并阅读给定的示例,我看到发生SLOT(startNextDownload())之后被激活downloadQueue.enqueue(url);了。我试图了解为什么这样做。

Art*_* R. 2

回答当前问题标题

每次调用都在调用它的线程的事件循环QTimer::singleShot(...)上执行**。如果从主线程调用,它将是以 开始的事件循环。app.exec()

根据 Qt-Network-Manager-Example,此函数在网络管理器填充 URL调用,因此将在队列完全填满后处理单次。不幸的是,qt 文档对此主题还不太清楚,因此有关事件处理等的更多信息,请查看此处


回答旧问题标题

在开始之前,计时器用于在额外的线程中进行下载。因此 GUI 保持响应。

完整的downloadNext()方法是递归的。它只会被调用一次,直到队列为空为止。看看这个:

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;
}
Run Code Online (Sandbox Code Playgroud)

队列为空后,每个方法都会返回,并且至少会打印下载完成的消息。

那么为什么这会起作用呢? 请参阅下面的第一章。