QT C++下载多个文件,总进度为
QT C++ download multiple files with progress total
我实现了下载多个文件,但我不知道如何实现下载的总进度条,这是常见的。
我的代码:
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);
}
如果有任何帮助和提示,我将不胜感激!非常感谢。
您可能需要迭代您的"currentDownloads"列表,并连接到每个列表的信号downloadProgress。然后将从所有插槽中调用您的插槽。在该插槽中,您必须将所有信息汇总为QNetworkReply::downloadProgress信号的参数。
您可以为当前下载列表的每个QNetworkReply实例创建一个专用对象,这样您就可以知道即将到来的信号属于哪个文件,但如果我没有弄错的话,您也可以为所有这些文件使用单个插槽,然后Qt中有一个元函数,它会告诉您信号来自哪个发件人。
附言:为了响应您对小示例的请求,这里有一种"直接"方法(不使用QSignalMapper或QObject::sender()):
像这样实现一个类"ProgressListener"(注意我在写伪代码,你需要添加/修复一些必要的东西才能使它真正工作):
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
中,每次向currentDownloads
添加新的QNetworkReply
对象时:1.创建ProgressListenner
的新实例并将其添加到downloadListenners
中。2.将特定QNetworkReply的信号连接到相应ProgressListener的插槽:connect(reply, SIGNAL(downloadProgress(qint64, qint64)), pListenner, SLOT(onDownloadProgress (qint64, qint64)));
这样,每当某个QNetworkReply触发其进度信号时,就会调用相应ProgressListener的插槽。
下一步是汇总所有下载的数字。一个简单的方法是:1.在ProgressListenner
类中再创建一个函数,并使其成为static
(重要)。假设函数的名称为CommonProgress
。2.在onDownloadProgress
函数调用结束时,也调用CommonProgress
3.在CommonProgress
函数中(注意线程安全!)迭代downloadListenners
的所有元素,并将它们的_lastKnownReceived
和_lastKnownTotal
相加。做必要的算术运算。。。不要忘记bytesTotal
可以是-1!!!
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到