2013-04-18 59 views
0

我正在开发一个Qt C++应用程序。我需要下载一些文件(可能很大)并向用户显示下载进度。要执行此任务,我用这个代码:C++ Qt从QNetworkRequest获取HTTP标头

QNetworkAccessManager* networkManager = new QNetworkAccessManager(); 

QNetworkRequest request(fileUrl); //fileUrl is a QUrl variable 
QVariant responseLength = request.header(QNetworkRequest::ContentLengthHeader); 
int fileSize = responseLength.toInt(); 
ui->progressBar->setMaximum(fileSize); 
QNetworkReply reply = networkManager->get(request); 
QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), 
       this, SLOT(downloadProgressChanged(qint64,qint64))); 

哪里downloadProgressChanged与此代码插槽:

void downloadProgressChanged(qint64 downloaded, qint64 total) 
{ 
    ui->progressBar->setValue(ui->progressBar->value() + 1); 
    ui->labelProgress->setText(QString::number((downloaded/1024))); 
} 

(我用QProgressBar命名progressBar显示进度和QLabel命名labelProgress显示下载的千字节)。

我的问题是我无法访问Content-Length标题(int fileSize值为0),所以我无法显示操作的进度。我检查了我的web服务器上的HTTP头 - Content-Length工作正常。

this SO question我读到我可以使用QNetworkReply::metaDataChanged()信号,但是如何使用它来显示进度?文档说,下载已经开始,但我需要得到标题内容之前下载将开始 - 设置我的progressBar信号可以发射。

回答

1

您是否尝试过使用readyRead信号?在插槽中,您可以准备GUI。像这样的东西务必做好工作:

connect(reply, SIGNAL(readyRead()), this, SLOT(updateProgressBar())) 
5

这不是你将如何从一个请求获得头信息:

QNetworkRequest request(fileUrl); //fileUrl is a QUrl variable 
QVariant responseLength = request.header(QNetworkRequest::ContentLengthHeader); 
int fileSize = responseLength.toInt(); 
ui->progressBar->setMaximum(fileSize); 

尝试使与QNetworkAccessManager的请求,然后得到自己想要的头从它返回的答复。有来自请求仅检索头信息的特殊方法:

QNetworkAccessManager::head(const QNetworkRequest & request) 

由于Qt的网络API是异步的,你必须将QNetworkAccessManager的成品(QNetworkReply *)信号连接到一个插槽,并获得在标题信息插槽。

以下是我会做:

void MainWindow::on_download_button_clicked(){ 
    QUrl url("http://someurl"); 
    QNetworkAccessManager * manager = new QNetworkAccessManager(this); 
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(getHeaders(QNetworkReply*))); 
    manager->head(QNetworkRequest(url)); 
} 

void MainWindow::getHeaders(QNetworkReply * reply){ 
    if (reply->operation() == QNetworkAccessManager::HeadOperation){ 
     int content_length = reply->header(QNetworkRequest::ContentLengthHeader).toInt(); 
    } 
}