<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span>
在看了foruok的
Qt Quick 之 QML 与 C++ 混合编程详解后,我决定在qt 4.8.1环境下试一试
然后就遇到了一些问题
自己写了个HttpManager类,在将其注册到qml中,调用的时候如下
NetworkManager {
id:net
url:"http://www.baidu.com"
method:NetworkManager.GET
}
上述的networkManager元素的方法为net.start()
使用start()方法后,就会向" http://www.baidu.com"请求GET
在将返回的数据写到一个文件里
在qml中第一次触发start(),往文件里写的是一个html内容
再一次在qml中触发start(),往文件里写的才是" http://www.baidu.com"的html文件的gzip
前后两次调用start()方法,GET到的内容是不一样的
第一次GET到的内容如下
<html>
<head>
<script language="javascript">setTimeout("location.replace(location.href.split(\"#\")[0])",2000);</script>
<script type="text/javascript" src="http://61.142.67.130:89/cookie/flash.js"></script>
<script language="javascript">setURL("61.142.67.130");supFlash();</script>
</head>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="0" height="0" id="m" align="center"><param name="allowScriptAccess" value="always" />
<param name="movie" value="http://61.142.67.130:89/cookie/flashcookie.swf" />
<param name="quality" value="high" />
<param name="FlashVars" value="fc=2308725444419&f=1346948874" />
<embed src="http://61.142.67.130:89/cookie/flashcookie.swf"FlashVars="fc=2308725444419&f=1346948874" quality="high" width="0" height="0" name="m" align="center" allowScriptAccess="always" type="application/x-shockwave-flash"pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</body>
</html>
在C++代码中,测试的时候,出现的是间隔问题,
若第一次启动程序(随便启动 HttpManager::start()方法),成功获取正确的网页,那么在下一次启动程序时,便会获取上述的html代码。
在第三次启动程序的时候,又能重新获取正确的网页,诸如...
若第一次启动程序(随便启动 HttpManager::start()方法),成功获取正确的网页,那么在下一次启动程序时,便会获取上述的html代码。
在第三次启动程序的时候,又能重新获取正确的网页,诸如...
遇到的问题,不知是我的HttpManager类写的有问题(我对网络编程还不是很熟,可能是我的C++代码中的HttpManager类没写好吧)
贴一下我写的Qt 的HttpManager类的头文件(已经设置可以注册到qml,也可以在c++代码中使用)
#ifndef HTTPMANAGER_H
#define HTTPMANAGER_H
#include <QString>
#include <QUrl>
#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkCookieJar>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
class HttpManager : public QObject
{
Q_OBJECT
Q_ENUMS(HTTPMETHOND)
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(HTTPMETHOND methond READ methond WRITE setMethond NOTIFY methondChanged)
public:
enum HTTPMETHOND {
NONE = 0,
GET = 1,
POST = 2,
HEAD = 3,
PUT = 4,
DELETE = 5
};
/*标记构造次数*/
static int index;
explicit HttpManager(QObject *parent = 0);
~HttpManager();
/*property url*/
QUrl url() const;
void setUrl(const QUrl &_url);
/*property methond*/
HTTPMETHOND methond() const;
void setMethond(HTTPMETHOND _Methond);
Q_INVOKABLE void postData(QString _postData);
signals:
void urlChanged(const QUrl &_url);
void methondChanged(HTTPMETHOND _Methond);
void finished();
public slots:
void start();
private:
void HTTPGet();
void HTTPPost();
protected:
void setRequsetRawHeaders(const QString &_headerName,const QString &_headerValue);
private slots:
void replyFinished(QNetworkReply* _reply);
private:
QNetworkAccessManager *mManager;
QString *mPostData;
QUrl *mUrl;
HTTPMETHOND mMethond;
QNetworkReply *mReply;
QNetworkRequest *mRequest;
QList<QNetworkCookie> mCookies;
};
#endif // HTTPMANAGER_H
Networkmanager类的实现
#include <QDebug>
#include <QByteArray>
#include <QSslConfiguration>
#include <QFile>
#include <QDir>
#include "httpmanager.h"
/*标记构造次数*/
int HttpManager::index = 0;
HttpManager::HttpManager(QObject *parent) :
QObject(parent)
,mManager(new QNetworkAccessManager)
,mPostData(new QString)
,mUrl(new QUrl)
,mMethond(NONE)
,mRequest(new QNetworkRequest)
{
/*标记构造次数*/
index++;
qDebug() << "index:" << index <<"here is the http manager!";
mManager->setCookieJar(new QNetworkCookieJar(this));
connect(mManager, SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply*)));
}
HttpManager::~HttpManager()
{
delete mUrl;
delete mPostData;
delete mRequest;
mReply->deleteLater();
mManager->deleteLater();
}
void HttpManager::start()
{
this->setRequsetRawHeaders("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0");
this->setRequsetRawHeaders("Accept","*/*");
this->setRequsetRawHeaders("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
this->setRequsetRawHeaders("Accept-Encoding","gzip, deflate");
this->setRequsetRawHeaders("DNT","1");
// this->setRequsetRawHeaders("Referer","https://ui.ptlogin2.qq.com/cgi-bin/logindaid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20140612002");
mRequest->setUrl(*mUrl);
switch(mMethond)
{
case NONE:
qDebug() << "error!";
break;
case GET:
qDebug() << "get methond";
this->HTTPGet();
break;
case POST:
qDebug() << "post methond";
break;
case HEAD:
qDebug() << "head methond";
break;
case PUT:
qDebug() << "put methond";
break;
case DELETE:
qDebug() << "delete methond";
break;
default:
break;
}
}
void HttpManager::HTTPGet()
{
mReply = mManager->get(*mRequest);
}
void HttpManager::HTTPPost()
{
mReply = mManager->post(*mRequest,mPostData->toAscii());
}
QUrl HttpManager::url() const
{
return *mUrl;
}
void HttpManager::setUrl(const QUrl &_url)
{
*mUrl = _url;
mRequest->setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
if (mUrl->scheme() == "https")
{
QSslConfiguration config;
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1);
mRequest->setSslConfiguration(config);
}
emit urlChanged(*mUrl);
}
HttpManager::HTTPMETHOND HttpManager::methond() const
{
return mMethond;
}
void HttpManager::setMethond(HTTPMETHOND _Methond)
{
mMethond = _Methond;
emit methondChanged(mMethond);
}
void HttpManager::postData(QString _postData)
{
*mPostData = _postData;
qDebug() << "mPostData:" << *mPostData;
}
void HttpManager::replyFinished(QNetworkReply *reply)
{
QFile *_tempFile = new QFile;
QString _file = "D://html.gz";
_tempFile->setFileName(_file);
if (mReply->error() != QNetworkReply::NoError)
{
qWarning() << "ERROR:" << mReply->errorString();
return;
}
else
{
if(!_tempFile->open(QFile::WriteOnly))
{
qDebug() << "can't open file for write";
return;
}
_tempFile->write(reply->readAll());
_tempFile->close();
}
}
void HttpManager::setRequsetRawHeaders(const QString &_headerName,const QString &_headerValue)
{
QByteArray _tempHeaderName = _headerName.toAscii();
QByteArray _tempHeaderValue = _headerValue.toAscii();
mRequest->setRawHeader(_tempHeaderName,_tempHeaderValue);
}
在qml中调用NetworkManager类
import QtQuick 1.1
import com.qyvlik.NetworkManager 1.0
Rectangle {
width: 400
height: 400
NetworkManager {
id:net
url:"http://www.baidu.com"
methond:NetworkManager.GET
}
Text {
width: parent.width-10
wrapMode: Text.WrapAnywhere
anchors.centerIn:parent
id: text
text: net.url;
font.family: "华文细黑"
font.pointSize: 11
horizontalAlignment: Text.AlignHCenter
}
Rectangle {
id:button
width:100
height: 60
color:"#7f92b3"
radius: 10
border.width: 2
border.color: "black"
Text {
id: buttonText
text: qsTr("start!")
anchors.centerIn:parent
}
anchors.right: parent.right
anchors.rightMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
MouseArea {
id:buttonArea
anchors.fill: button
onClicked: {
net.start();
}
}
}
}
在贴一下在么把c++代码注册到qml 中去吧
qmlRegisterType<HttpManager>("com.qyvlik.NetworkManager", 1, 0, "NetworkManager");
将HttpManager注册到qml中去,模块名为com.qyvlik.NetworkManager,主版本号为1,副本为0,element名为NetworkManager