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;
}
}
#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;
}
}
#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();
}
#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.
原因还在查找中。