qthread QNetworkAccessManager QEventLoop
進程通過QNetworkAccessManager 進行http請求。代碼如下:
//qhttp.h
#ifndef QHTTP_H
#define QHTTP_H
#include <QtGui/QWidget>
#include "ui_qhttp.h"
#include <QNetworkAccessManager>
#include <QUrl>
class QPushButton;
class QDialogButtonBox;
class QNetworkReply;
class qhttp : public QWidget

{
Q_OBJECT
public:
qhttp(QWidget *parent = 0);
~qhttp();
void startRequest(QUrl url);
private:
Ui::qhttpClass ui;
QPushButton *downloadButton;
QDialogButtonBox *buttonBox;
QUrl url;
QNetworkAccessManager qnam;
QNetworkReply *reply;
private slots:
void downloadFile();
void httpFinished();
};
#endif // QHTTP_H

//qhppt.cpp
#include "qhttp.h"
#include <QtGui>
#include <QtNetwork>
#include <iostream>
using namespace std;
qhttp::qhttp(QWidget *parent)
: QWidget(parent)

{
ui.setupUi(this);
downloadButton = new QPushButton(tr("Download"));
downloadButton->setDefault(true);

buttonBox = new QDialogButtonBox;
buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
}
qhttp::~qhttp()

{
}
void qhttp::downloadFile()

{
cout<<"downloadFile"<<endl;
url = "http://www.baidu.com/";
startRequest(url);
}
void qhttp::startRequest(QUrl url)

{
cout<<"startRequest"<<endl;
reply = qnam.get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
}
void qhttp::httpFinished()

{
cout<<"httpFinished"<<endl;
if(reply->error())
{
cout<<"error:"<<qPrintable(reply->errorString())<<endl;
}
else
{
cout<<"right"<<endl;
}
}
但當主進程開辟線程來執行http請求時,卻無法成功。
//qhttp.h
#ifndef QHTTP_H
#define QHTTP_H
#include <QtGui/QWidget>
#include "ui_qhttp.h"
#include <QNetworkAccessManager>
#include <QUrl>
class QPushButton;
class QDialogButtonBox;
class QNetworkReply;
class qhttpThread;
class qhttp : public QWidget

{
Q_OBJECT
public:
qhttp(QWidget *parent = 0);
~qhttp();
void startRequest(QUrl url);
private:
Ui::qhttpClass ui;
QPushButton *downloadButton;
QDialogButtonBox *buttonBox;
QUrl url;
QNetworkAccessManager qnam;
QNetworkReply *reply;
qhttpThread *httpthread;
private slots:
void downloadFile();
void httpFinished();
};
#endif // QHTTP_H


//qhttp.cpp
#include "qhttp.h"
#include "qhttpThread.h"
#include <QtGui>
#include <QtNetwork>
#include <iostream>
using namespace std;
qhttp::qhttp(QWidget *parent)
: QWidget(parent)

{
ui.setupUi(this);
downloadButton = new QPushButton(tr("Download"));
downloadButton->setDefault(true);

buttonBox = new QDialogButtonBox;
buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
}
qhttp::~qhttp()

{
}
void qhttp::downloadFile()

{
cout<<"downloadFile"<<endl;
//url = "http://www.baidu.com/";
//startRequest(url);
httpthread = new qhttpThread(this);
httpthread->start();
}
void qhttp::startRequest(QUrl url)

{
cout<<"startRequest"<<endl;
reply = qnam.get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
}
void qhttp::httpFinished()

{
cout<<"httpFinished"<<endl;
if(reply->error())
{
cout<<"error:"<<qPrintable(reply->errorString())<<endl;
}
else
{
cout<<"right"<<endl;
}
}
此時會出現程序運行崩潰、沒有執行http請求任務等情況。
簡單說一下注意事項:
1 線程中的run函數返回后線程即結束,根本無法等到reply的finished信號。因此需要加入QEventLoop來掛起線程。
2 通過connect設置信號槽,需要QObject的支持,因此在構造函數里與頭文件中需要修改代碼。
最終的修改代碼如下:
//qhttpThread.h
#ifndef QHTTPTHREAD_H_
#define QHTTPTHREAD_H_
#include <QThread>
#include <QObject>
#include <QNetworkAccessManager>
#include <QUrl>
class QNetworkReply;
class QEventLoop;

class qhttpThread : public QThread
{
Q_OBJECT
public:
qhttpThread(QObject *parent = 0);
virtual ~qhttpThread();
void run();
private:
QUrl url;
QNetworkAccessManager qnam;
QNetworkReply *reply;
QEventLoop *loop;
void startRequest(QUrl url);
private slots:
void httpFinished();
};
#endif /* QHTTPTHREAD_H_ */



//qhttpThread.cpp
#include "qhttpThread.h"
#include <QtNetwork>
#include <QEventLoop>
#include <iostream>
using namespace std;

qhttpThread::qhttpThread(QObject *parent) : QThread(parent)
{
// TODO Auto-generated constructor stub
}

qhttpThread::~qhttpThread()
{
// TODO Auto-generated destructor stub
}
void qhttpThread::run()

{
cout<<"run"<<endl;
url = "http://www.baidu.com/";
startRequest(url);

exec();
cout<<"run end"<<endl;
}
void qhttpThread::startRequest(QUrl url)

{
cout<<"startRequest"<<endl;
loop = new QEventLoop;
reply = qnam.get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
loop->exec();
cout<<"startRequest end"<<endl;
}
void qhttpThread::httpFinished()

{
cout<<"httpFinished"<<endl;
if(reply->error())
{
cout<<"error:"<<qPrintable(reply->errorString())<<endl;
}
else
{
cout<<"right"<<endl;
}
loop->quit();
}
這樣,就可以對http進行請求了。
但在真正的執行中,當關閉界面程序時出現彈出框,提示:This application has requested the Runtime to terninate it in an unusual way.
原因還在查找中。
posted on 2011-01-04 09:28 seahouse 閱讀(3693) 評論(0) 編輯 收藏 引用 所屬分類: Qt

