简体   繁体   English

C ++ Qt从QNetworkRequest获取HTTP标头

[英]C++ Qt get HTTP headers from QNetworkRequest

I am developing a Qt C++ application. 我正在开发Qt C ++应用程序。 I need to download some files (which can be large) and show downloading progress to user. 我需要下载一些文件(可能很大),并向用户显示下载进度。 To perform this task, I use this code: 为了执行此任务,我使用以下代码:

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

Where downloadProgressChanged is a slot with this code: 其中downloadProgressChanged是具有以下代码的插槽:

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

(I use QProgressBar named progressBar to show progress and QLabel named labelProgress to show downloaded kilobytes). (我使用QProgressBar命名为progressBar来显示进度,并使用QLabel命名为labelProgress来显示下载的千字节)。

My problem is that I can't access Content-Length header ( int fileSize value is 0) and so I am not able to show the progress of the operation. 我的问题是我无法访问Content-Length标头( int fileSize值为0),因此无法显示操作进度。 I checked HTTP headers on my web-server - Content-Length works fine. 我在网络服务器上检查了HTTP标头-Content-Length正常工作。

In this SO question I read that I can use QNetworkReply::metaDataChanged() signal, but how can I use it to show progress? 这个SO问题中,我读到可以使用QNetworkReply::metaDataChanged()信号,但是如何使用它显示进度? Documentation says that the signal can be emitted when downloading has been already started , but I need to get header content before downloading will start - to set up my progressBar. 文档说, 已经开始下载时可以发出信号,但是我需要开始下载之前获取标头内容-设置我的progressBar。

This isn't how you would get header information from a request: 这不是从请求中获取标头信息的方式:

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

Try making the request with the QNetworkAccessManager and then getting the header you want from the reply that it returns. 尝试使用QNetworkAccessManager发出请求,然后从返回的回复中获取所需的标头。 There is a special method for retrieving only header information from a request: 有一种特殊的方法可仅从请求中检索标头信息:

QNetworkAccessManager::head(const QNetworkRequest & request)

Since Qt's network API is asynchronous, you have to connect the QNetworkAccessManager's finished(QNetworkReply*) signal to a slot, and get the header information in the slot. 由于Qt的网络API是异步的,因此您必须将QNetworkAccessManager的finish(QNetworkReply *)信号连接到插槽,并在插槽中获取标头信息。

Here's how I'd do it: 这是我的处理方式:

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

Have you tried using readyRead signal? 您是否尝试过使用readyRead信号? And in slot you could prepare the GUI. 在插槽中,您可以准备GUI。 Something like this shoud do the work: 像这样的事情应该做的工作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM