QNetworkAccessManager不使用信号/槽机制来获得QNetworkReply的解决办法
来源:互联网 发布:韩国剑灵捏脸数据 编辑:程序博客网 时间:2024/06/05 09:25
正在做一个第三方微信企业要接口的项目,JAVA的实现方法比较简单,网上资料也很多。
但是我需要在C++下实现,微信企业号接口大多都是https的GET/POST方法实现的。
Qt提供了一个封装好的类QNetworkAccessManager,就不需要使用windows的套接字来编程了,也脱离的平台限制。
上图是我从http://blog.csdn.net/chenlong12580/article/details/7392766 当中借来得,这位兄弟也很好的演示了QNetworkAccessManager的基本调用方法。
但是QNetworkAccessManager是为图形界面而设计的,当Manager得到finished()信号时,使用一个SLOT函数去做读取数据的事,这对于显示在GUI的数据时,可以说不能再好用了。
但是微信企业号在调用任何的接口之前,都需要获得一个认证,就是access_token,需要使用GET方式来获得,这使得我需要将获得access_token的方法封装成一个函数,以便在每次具体的如发送微信之前,调用它。
贴上代码:
void MainWindow::getAccessToken(){ QNetworkAccessManager *manager = new QNetworkAccessManager(this); connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(finishedSlot(QNetworkReply*)),Qt::DirectConnection); QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(ACCESS_TOKEN_URL)));}
void MainWindow::finishedSlot(QNetworkReply* reply){ qDebug()<<"start"; QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if(reply->error()==QNetworkReply::NoError) { QByteArray bytes = reply->readAll(); QString rlt =QString::fromUtf8(bytes); accessToken = rlt; } reply->deleteLater(); //ACCESS_FLAG = true; qDebug()<<"finished";}
以上就是按照官方文档来实现的代码片。
如果我再main中直接调用
getAccessToken()的话,程序会直接运行之后的代码片,而不会先运行SLOT,因为他们在同一线程。
而如果用C++11的 thread.h 用多线程调用,编译器也不认QNetworkReply为valid的type,并且多线程也不符合代码的逻辑,因为主线程要等待子线程,且只有一个子线程。
解决的办法就是使用QEventLoop:直接上代码:
void MainWindow::getAccessToken(){ QEventLoop temp_loop; QNetworkAccessManager *manager = new QNetworkAccessManager(this); QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(ACCESS_TOKEN_URL))); connect(reply, SIGNAL(finished()), &temp_loop, SLOT(quit())); temp_loop.exec(); qDebug()<<"start"; QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if(reply->error()==QNetworkReply::NoError) { QByteArray bytes = reply->readAll(); QString rlt =QString::fromUtf8(bytes); accessToken = rlt; qDebug()<<accessToken; } reply->deleteLater(); qDebug()<<"finished";}通过比较之前的代码片,我想应该很好看出不同,不仅within一个方法,而且代码也更好读更短,QNetworkAccessManager的操作封装在一个函数中了。
这里还要提一点,按照文档的资料,QNetworkReply的waitForReadyRead()函数,应该也可以完成上述操作,但是我发现不管设置几秒的等待,函数都无脑回false,看网上说Qt在某个版本后这个函数失效了,我用的是Qt5.4,可能4.x下可以用,应该也是可以实现的的。
- QNetworkAccessManager不使用信号/槽机制来获得QNetworkReply的解决办法
- QNetworkAccessManager 放到线程中使用finished信号不触发
- QNetworkAccessManager 放到线程中---finished信号不触发
- QWebEngineView使用QNetworkAccessManager的QNetworkCookieJar
- QML中信号槽机制的使用
- QNetworkReply
- 信号处理机制的使用
- 嵌入式 QT开发使用信号和槽的机制
- 非Qt工程使用Qt的信号槽机制
- CSDN下载不来资料的解决办法
- QT的信号/槽机制
- QT的信号/槽机制
- Qt的信号槽机制
- 如何用信号来实现超时的读写机制
- pyqt通过信号槽机制来退出线程
- qt 的QNetworkAccessManager的使用和防止内存泄漏
- 【程序员一枚】Qt网络开发之QNetworkAccessManager的使用
- 程序员一枚】Qt网络开发之QNetworkAccessManager的使用
- vSphere Management Assistant(VMA) 命令行修改IP
- 第十四周项目1验证折半查找算法
- c语言中的一些变量!
- SQL笔记(10)_2_CUBE,ROLLUP,GROUPING
- Nginx配置SSL证书部署HTTPS网站
- QNetworkAccessManager不使用信号/槽机制来获得QNetworkReply的解决办法
- VS C++ 控件使用
- 给开发板烧写程序的N种方式
- c++/c实现线程池
- 欧拉函数求法与欧拉筛法求素数
- hdu1024 Max Sum Plus Plus
- 第十周项目3-利用二叉树遍历思想解决问题(4)
- 轻松学习JavaScript十:JavaScript的Date对象制作一个简易钟表
- iOS之lipo