我是初学者学习Qt,并试图了解Qt为下载操作提供了
example.在
downloadmanager.cpp,成员函数如下:
void DownloadManager::append(const QUrl &url)
{
if (downloadQueue.isEmpty())
QTimer::singleShot(0, this, SLOT(startNextDownload()));
downloadQueue.enqueue(url);
++totalCount;
}
>我很困惑为什么,如果downloadQueue为空,则需要在添加url之前激活startNextDownload(). (注意:如果downloadQueue为空,则startNextDownload()结束程序)
>我不确定为什么:QTimer :: signleShot(x,y,z)已被使用.据我所知,一个定时器以0毫秒的延迟激活插槽.
>我无法从查看Qt助手中弄清楚singleShot是否是以给定的毫秒间隔重复激活到插槽的一次性设置或者是否是一次
澄清:
我是初学者,例如:
statement1;
statement2;
我习惯于在继续使用statement2之前看到statement1正在运行和完成.但是尝试学习Qt并阅读给定的例子,我看到在downloadQueue.enqueue(url)之后激活了SLOT(startNextDownload());已经发生了.我试图理解为什么这样做.
最佳答案 回答当前的问题标题
每次调用QTimer :: singleShot(…)都会在调用它的线程的事件循环上执行**.如果从主线程调用,它将是用app.exec()启动的事件循环.
根据Qt-Network-Manager-Example,在网络管理器填充URL之后调用此函数,以便在队列完全填满后处理单击. qt文档还不是很清楚这个主题,所以有关事件处理等的更多信息,请查看here.
回答旧问题
在我开始之前,计时器用于在额外的线程中进行下载.因此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;
}
队列为空后,每个方法都返回,并且至少会打印下载完成的消息.
那么为什么这样呢?
请参阅下面的第一章.