在Qt中,使用QNetworkAccessManager类就可以完成基于Http协议的数据上传和下载,该类既可以发送网络请求,也可以接收网络回复。而具体的网络请求是通过QNetworkRequest类发送的,具体的网络回复是通过QNetworkReply类来接收的。
本文将利用上面的几个类实现一个简单的Http客户端,从指定的网址下载数据。
基本原理
由于QNetworkAccessManager类中包含了一组标准的数据请求函数,因此可以通过该类的对象发送数据请求函数;每个请求函数执行完毕时都回返回一个QNetworkReply对象。当所有请求的数据都到达本地后,将引发一个finished()信号,该信号关联了一个处理返回数据的槽函数。具体的实现可参考下述代码:
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply*))); manager->get(QNetworkRequest(QUrl( "http://www.kerneltravel.net/"))); }
可以看到,上述的基本原理大部分都在构造函数中完成。首先创建了一个QNetworkAccessManager对象manager;接着将manager所引发的finished()信号与replyFinished()槽进行关联;最后通过get()发送数据请求。
get()用于发送请求并获得目标地址中的数据,具体的数据请求则是通过创建一个QNetworkRequest类的对象而完成的。只要数据请求发送成功,则开始下载数据。当所有的数据下载完成后,就返回一个QNetworkReply类型的对象。同时manager对象将发送一个finished()信号,引发replyFinished槽函数的执行。
当执行上述的槽函数时,就说明目标地址的数据已经下载完毕。此时槽函数要做的就是将这些数据显示出来。这里我们只只对文本数据进行转换。对这些数据的转换动作可参考下述的代码:
void Widget::replyFinished(QNetworkReply *reply) { QTextCodec *codec = QTextCodec::codecForName("utf8"); QString all = codec->toUnicode(reply->readAll()); ui->textEdit->setText(all); reply->deleteLater(); }
为了能够正确显示中文,我们创建QTextCodec对象。利用readAll函数可以读取数据请求返回的所有数据,并且利用toUnicode函数将这些数据转换成QString类型。最后在用户界面中的文本编辑器中显示出来。
按照上面的方法就可以下载指定地址的数据。如下图:
当返回的数据显示完毕后,利用deleteLater函数将返回的数据删除。
上述的执行过程用数据流图表示如下:
上述内容只是对基于Http协议的数据下载做了简单的描述,并没有对界面设计作过多的介绍,关于界面的设计可见参考1。下文将对这个基本的Http客户端进行改造。
参考:
1. Qt Assistant
2. http://www.yafeilinux.com/?p=734
3. C++ GUI Qt 4编程(第二版); 电子工业出版社;Blanchette,J,Summerfield,M 著;闫锋欣 等译;