QT C ++下载多个文件,总进度

时间:2014-11-09 15:54:14

标签: c++ qt download qfile

我意识到下载了多个文件,但我不知道如何实现下载的总进度条,这很常见。

我的代码:

QNetworkAccessManager manager;
QList<QNetworkReply *> currentDownloads;

void MainWindow::checkUpdate()
{
        QStringList files;
        files << "http://cavexp.net/uploads/game/Theugry/zips/resourcepacks.zip"
              << "http://cavexp.net/uploads/game/Theugry/zips/resourcepacks.zip";

        doDownload(files);
}

void MainWindow::doDownload(const QVariant& v)
{
    if (v.type() == QVariant::StringList) {
        foreach (QString url, v.toStringList()) {
            QNetworkReply* reply = manager.get(QNetworkRequest(QUrl(url)));

            connect(&manager, SIGNAL(downloadProgress(qint64, qint64)),
                this, SLOT(updateDownloadProgress(qint64, qint64)));

            currentDownloads.append(reply);
        }
    }
}

void MainWindow::downloadFinished(QNetworkReply *reply)
{
    currentDownloads.removeAll(reply);
    reply->deleteLater();
}

void MainWindow::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}

如果有任何帮助和提示,我将不胜感激!谢谢。

1 个答案:

答案 0 :(得分:1)

你可能需要迭代你的当前下载&#39;列出并连接到每个人的信号downloadProgress。然后你的所有插槽都会调用你的插槽。在那个插槽中,您必须总结作为QNetworkReply :: downloadProgress信号参数的所有信息。

您可以为currentDownloads列表的每个QNetworkReply实例创建一个专用对象,以便您知道即将到来的信号属于哪个文件,但如果我没有误会,您也可以为所有这些文件使用单个插槽,然后有Qt中的元函数将告诉您信号来自哪个发送者。

P.S。为了回应您对小例子的要求,这里是&#34;直接&#34;方法(不使用QSignalMapper或QObject :: sender()):

实施一个类&#34; ProgressListenner&#34;这样的事情(要注意我正在写伪代码,你需要添加/修复一些必要的东西才能让它真正起作用):

class ProgressListenner
{
   public:
   ProgressListenner() : _lastKnownReceived(0), _lastKnownTotal(0){}

   qint64 _lastKnownReceived;
   qint64 _lastKnownTotal;

   slots:
      onDownloadProgress ( qint64 bytesReceived, qint64 bytesTotal )
      {
          _lastKnownReceived = bytesReceived;
          _lastKnownTotal = bytesTotal;
      }
}

在您的行QList<QNetworkReply *> currentDownloads;之后添加QList<ProgressListenner*> downloadListenners;。每次向foreach添加新的QNetworkReply对象时,currentDownloads内部也会: 1.创建ProgressListenner的新实例并将其添加到downloadListenners。 2.将特定QNetworkReply的信号连接到相应的ProgressListenner插槽:connect(reply, SIGNAL(downloadProgress(qint64, qint64)), pListenner, SLOT(onDownloadProgress (qint64, qint64)));

这样,每次有一些QNetworkReply触发它的进度信号时,都会调用相应ProgressListenner的插槽。

下一步是总结所有下载中的数字。一个简单的方法是: 1.在ProgressListenner类中再创建一个函数,并使其成为static(重要)。假设函数的名称是CommonProgress。 2.在onDownloadProgress函数调用结束时,也可以调用CommonProgress 3.在CommonProgress函数中(注意线程安全!)迭代downloadListenners的所有元素并总结他们的_lastKnownReceived_lastKnownTotal。做必要的算术......不要忘记bytesTotal可以是-1 !!!