【问题标题】:QT C++ download multiple files with progress totalQT C++ 下载多个文件,进度总计
【发布时间】:2014-11-09 15:54:14
【问题描述】:

实现了下载多个文件,但是不知道怎么实现下载的总进度条,很常见。

我的代码:

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);
}

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

【问题讨论】:

  • manager 没有信号 downloadProgress 不是吗,也许你的意思只是 reply connect(reply, SIGNAL(downloadProgress(qint64, qint64)),this, SLOT(updateDownloadProgress(qint64, qint64)));
  • @Chernobyl 我不知道如何实现它。你能展示一个工作的例子吗?我将不胜感激!
  • @Chernobyl по-русски грамотнее объясню。 Реализовано скачивание файлов, хочу вывести общий прогресс их скачивания。
  • @John перевожу на русский то, что сказал Chernobyl: у класса QNetworkAccessManager (смотрим здеся: qt-project.org/doc/qt-5/qnetworkaccessmanager.html) нет сигнала, который бы сообы Сначала нужно у этого менеджера попросить QNetworkReply с помошью функции get(), а у того уже такой сигнал есть。 Смотрим пример тута - qt-project.org/doc/qt-4.8/… (ищем строку currentDownload = manager.get(request); )
  • @mvidelgauz спасибо, но в этом примере показывается именно прогресс для 1 файла。 Как реализовать общий прогресс бар скачивания нескольких файлов? Заранее спасибо!

标签: c++ qt download qfile


【解决方案1】:

您可能需要遍历您的“currentDownloads”列表并连接到每个人的信号downloadProgress。然后您的插槽将从所有这些中调用。在该插槽中,您必须汇总所有作为 QNetworkReply::downloadProgress 信号参数的信息。

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

附:为了回应您对小例子的要求,这里是“直截了当”的方法(不使用 QSignalMapper 或 QObject::sender()):

实现一个类似这样的类“ProgressListenner”(注意我正在编写伪代码,您需要添加/修复一些必要的东西才能使其真正工作):

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

   qint64 _lastKnownReceived;
   qint64 _lastKnownTotal;

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

在你的QList&lt;QNetworkReply *&gt; currentDownloads; 之后添加QList&lt;ProgressListenner*&gt; 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!!!

【讨论】:

  • Спасибо, что откликнулись! Если честно, не представляю как это реализовать。 Выможете показать небольшой пример? Я был бы очень благодарен!感谢您的帮助!老实说,不知道如何实现它。你能举一个小例子吗?我将不胜感激!
  • @John 我在我的答案中添加了一些伪代码。如果您需要更多解释,请告诉我...
  • в очередной раз спасибо, но я понял лишь отчасти, было бы очень замечательно если бы вы расскали борно боелее подрно再次感谢您,但我只是部分意识到,如果您能说得更详细一些,那就太好了。
  • Если Вам будет удобнее, то я могу скинуть весь проект。如果你愿意,我可以扔掉整个项目。
  • Скинте на michael@videlgauz.com, хотя мне кажется, что это противоречит правилам этого сайта。 В любом случае, без самостоятельной работы Вам не обойтись )))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
相关资源
最近更新 更多