QNetworkAccessManager学习笔记

http://blog.csdn.net/xiangzi_011/article/details/25912727

刚刚接触QT5不久,争取把相关学习的过程都记录一下,以备以后的回顾。如有问题,还请高手指点一二。

在 QtDoc 5.2版本的《C++ API changes》文档中明确提到QFtpQUrlInfoQHttp这几个类在QT5版本都已经不再使用,取而代之的是QNetworkAccessManager,QNetworkRequest和QNetworkReply。今天就来简单的先熟悉一下基本用法。我这里打算实现一个简单的get一个网页,简单显示出来的小demo。




这是最终的效果图,由QWebView控件显示最后的数据,这不是重点,主要是发送request和解析reply的过程。


1)QNetworkAccessManager的简单使用

首先创建一个QNetworkAccessManager实例m_netManager,用来对联网进行管理。

m_netManager = new QNetworkAccessManager(this);
connect(m_netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));//信号槽关联

点击Get按钮后触发获取动作,将lineEdit中的地址转化为url,通过QNetworkRequest类封装成一个request,然后调用m_netManager的get方法发送请求。注意需要将QNetworkAccessManager的finished信号关联一个处理reply的槽函数,当一次联网结束,finished信号会发送。


void MainWindow::on_pushButton_clicked()
{
    QUrl url(ui->lineEdit->text());
 
    m_netManager->get(QNetworkRequest(url)); //发送请求
}

下面来看看槽函数都做了什么,直接看代码。

int MainWindow::finishedSlot(QNetworkReply* reply)
{
 
    QVariant statusCode =
        reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
 
    qDebug() << "statusCode is " << statusCode.toString();
 
    QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
 
    QString charset = contentType.mid(contentType.indexOf("charset=") + QString("charset=").length());
 
    int result = 0;
 
    do
    {
        if (statusCode.toInt() == 301 || statusCode.toInt() == 302)
        {
            // Or the target URL if it was a redirect:
            QVariant redirectionTargetUrl =
                reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
 
            qDebug() << "redirection Url is " << redirectionTargetUrl.toString();
            QUrl url(redirectionTargetUrl.toString());
 
            m_netManager->get(QNetworkRequest(url));
            result = -2;
            break;
        }
 
        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray bytes = reply->readAll();  // bytes
            QString result;
 
            if (charset.compare("utf-8") == 0)
            {
                 result = QString::fromUtf8(bytes);
            }
            if (charset.compare("gbk") == 0)
            {
                QTextCodec *gbk = QTextCodec::codecForName("GB18030");
                result = gbk->toUnicode(bytes);
            }
 
            ui->webView->setHtml(result);//直接用QWebView的setHtml直接加载返回的html数据
        }
        else
        {
            //error here
            result = -1;
            break;
        }
    }while(0);
 
 
    reply->deleteLater();//注意这里要自己释放reply,否则内存泄漏
 
    return result;
}
 
 
 

 

所有的联网结果都在QNetworkReply实例中一并返回来,这里我们按照最常规的逻辑,只是把返回的网页显示数据显示到QTextBrowser中。这里注意跳转的情况。根据QNetworkReply的attribute方法我们可以返回的想要的一些属性值,例如QNetworkRequest::HttpStatusCodeAttribute可以获取状态码,QNetworkRequest::RedirectionTargetAttribute可以获取到重定向地址,还有很多属性,大家可以仔细看。我这里只是简单的处理了一下301,302跳转。如果没有发生异常,那么我们通过QNetworkReply实例把得到的数据读出来,这里我用readAll方法一次性读出。这里还稍微处理了一下contentType中charset的问题,因为网站的charset设置不同,所以要单独处理一下。例子比较简单,算是入门级别的东西。


2)QNetworkRequest

QNetworkRequest是和QNetworkAccessManager配合使用的一个类,主要负责设置request的相关参数以能够满足特殊的需求。之前我只是通过url来生成一个request,没有做任何配置。当然QT在底层做了默认的http配置。可以参考源码中prepareRequest方法。
函数原型为:

void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)


可以通过setHeader或者setRawHeader来设置http的相关参数,setHeader是设置QT预设好的KnownHeaders(参看QT文档),例如想设置都有的User-Agent,就可以通过如下方法做到:

request.setHeader(QNetworkRequest::UserAgentHeader,"your own agent");

如果要设置KnownHeaders中未列举的类型时,可以调用setRawHeader做到,直接引用官网给的代码说明。

request.setRawHeader("Last-Modified", "Sun, 06 Nov 1994 08:49:37 GMT");

当然可以通过header和rawHeader方法返回相应的header数据,注意:这里只能获取到你自己通过setHeader或者setRawHeader设置的header参数(目前是这么理解的,看到源码是自己设置的参数会单独保存)。

另外可以使用QList<QByteArray> QNetworkRequest::rawHeaderList() const 方法将全部header返回。


3)QNetworkReply

QNetworkReply实例拥有通过QNetworkAccessManager发送的request的所有头部信息和具体数据。上面已经说明了一些简单的使用,具体更深入的用法,还未全面看,大家自己研究下。

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值