说明
- QT网络模块中的QNetworkAccessManager类提供了统一的网络访问管理接口,不仅仅支持http协议,还支持ftp,HTTPS等协议;QNetworkRequest封装了网络请求接口;QNetworkReply封装了网络回复接口。
- Tip:Qt4x分别使用QFtp和QHttp,Qt5以后统一用QNetworkAccessManager。
使用
基本使用
QT += network
- 创建QNetworkAccessManager对象
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//绑定请求结束信号
connect(manager,SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply*)));
QNetworkReply* reply = manager->get(QNetworkRequest(QUrl("http://wap.foolog.sinaapp.com")));
QJsonObject json;
json.insert("account", QString("abc"));
json.insert("passwd", QString("123456"));
QJsonDocument document;
document.setObject(json);
QByteArray byte_array = document.toJson(QJsonDocument::Compact);
//设置url
QString url = "http://192.168.70.120:8080/login";
//设置头信息
QNetworkRequest requestInfo;
requestInfo.setUrl(QUrl(url));
requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
QNetworkReply* reply = manager->post(requestInfo, byte_array);
- 其它类型请求(post其它方式,put,delete等)类似。
特殊用法
- 阻塞式的获取结果,默认请求结束是通过信号通知,可以通过QEventLoop改为阻塞式,示例如下:
QEventLoop loop;
QNetworkReply *reply;
request.setUrl(QUrl(mUrl));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
reply = m_manager->post(request, data.toUtf8());
connect(m_manager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit())); // connect
loop.exec();
QByteArray byteArray = reply->readAll();
- QUrlQuery使用
- QUrlQuery的用途是url拼接,取代字符串拼接方式。
QUrl url("http://xxxxx/post.php");
QUrlQuery tt;
tt.addQueryItem("post","000");
tt.addQueryItem("action","edit");
tt.addQueryItem("name","techieliang");
url.setQuery(tt);
qDebug()<<url.url();
//http://xxxxx/post.php?post=000&action=edit&name=techieliang
url.setUrl("http://xxxxx/post.php?");
//http://xxxxx/post.php?
- QUrl和QUrlQuery是相互独立的,只有setQuery和setUrl时才会更改最终结果。
注意点
- 返回的QNetworkReply对象不会自动释放空间,一定要主动处理内存释放,可以调用QObject::deleteLater。
- 最重要的是:不能将请求放在UI线程,网上博客中的例子大部分是错误的,出现异常时会导致UI线程阻塞,程序无响应,IO操作应该放在别的线程中处理。