[英]Why does this Qt signal never get emitted?
我正在尝试从网页中获取数据,但是信号finished()
从未发出!!! 我知道我一定在做错事,但无法弄清楚那是什么。
# webservice.h
class WebService:public QObject
{
Q_OBJECT
public:
explicit WebService(QObject *parent=0);
void getRequest(const QString &urlString);
signals:
void networkError(QNetworkReply::NetworkError ne);
void finished(QNetworkReply*);
public slots:
void parseNetworkResponse(QNetworkReply* finished);
private:
QNetworkAccessManager *netMgr;
public:
QByteArray data;
};
#webservice.cpp
WebService::WebService(QObject *parent):QObject(parent)
{
netMgr = new QNetworkAccessManager;
connect(netMgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(parseNetworkResponse(QNetworkReply*)));
}
void WebService::getRequest(const QString &urlString)
{
QUrl url(urlString);
QNetworkRequest req;
emit finished(netMgr->get(req));
}
void WebService::parseNetworkResponse(QNetworkReply *finished)
{
if (finished->error() != QNetworkReply::NoError)
{
emit networkError(finished->error());
return;
}
data = finished->readAll();
qDebug() << data;
}
data
永远不会得到预期的值。
您没有将URL传递给您创建的QNetworkRequest
。 尝试:
QNetworkRequest req(url);
在WebService::getRequest()
内部。
根据要求,对源进行了修改,使其可以在QtCreator中作为控制台应用程序项目中的单个main.cpp
文件进行编译和工作:
#include <QCoreApplication>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QByteArray>
#include <QString>
#include <QDebug>
//# webservice.h
class WebService:public QObject
{
Q_OBJECT
public:
explicit WebService(QObject *parent=0);
void getRequest(const QString &urlString);
signals:
void networkError(QNetworkReply::NetworkError ne);
void finished(QNetworkReply*);
public slots:
void parseNetworkResponse(QNetworkReply* finished);
private:
QNetworkAccessManager *netMgr;
public:
QByteArray data;
};
//#webservice.cpp
WebService::WebService(QObject *parent):QObject(parent)
{
netMgr = new QNetworkAccessManager;
connect(netMgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(parseNetworkResponse(QNetworkReply*)));
}
void WebService::getRequest(const QString &urlString)
{
QUrl url(urlString);
QNetworkRequest req(url);
emit finished(netMgr->get(req));
}
void WebService::parseNetworkResponse(QNetworkReply *finished)
{
if (finished->error() != QNetworkReply::NoError)
{
qDebug() << "QNetworkReply error: " << finished->error();
emit networkError(finished->error());
return;
}
data = finished->readAll();
qDebug() << data;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WebService web;
web.getRequest("http://www.google.com");
return a.exec();
}
#include "main.moc"
进行的较小修改:
main()
,它调用了WebService::getRequest()
main.cpp
文件的末尾添加了#include "main.moc"
,因此qmake可以将它作为单个独立的.cpp文件正确地“ moc-ify” qDebug()
输出 最后要做的一件事是在项目的.pro文件中添加QT += network
,以便将Qt网络模块添加到链接步骤和标头搜索路径中。
2013年10月15日更新
从您的评论看来,您希望QNetworkAccessManager::get()
调用是同步的。 我添加了示例程序的另一个版本,它将在WebService::getRequest()
阻塞,直到收到请求的finished
信号为止。 请注意,此示例在错误处理方面的执行不多,并且如果netwrok请求未能及时完成,可能会执行得很差。 除了示例代码或学习代码以外,必须适当地处理错误和超时。
此示例中的基本思想是,异步Qt网络模型中发出的信号由框架的事件循环驱动。 因此,当发出请求时,将创建一个新的“嵌套”事件循环,然后WebService::getRequest()
函数执行该循环(并保持在那里),直到finished
信号的处理程序告诉事件循环退出为止。
#include <QCoreApplication>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QEventLoop>
#include <QByteArray>
#include <QString>
#include <QDebug>
//# webservice.h
class WebService:public QObject
{
Q_OBJECT
public:
explicit WebService(QObject *parent=0);
void getRequest(const QString &urlString);
signals:
void networkError(QNetworkReply::NetworkError ne);
//void finished(QNetworkReply*);
public slots:
void parseNetworkResponse(QNetworkReply* finished);
private:
QNetworkAccessManager *netMgr;
QEventLoop request_event_loop;
public:
QByteArray data;
};
//#webservice.cpp
WebService::WebService(QObject *parent):QObject(parent)
{
netMgr = new QNetworkAccessManager;
connect(netMgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(parseNetworkResponse(QNetworkReply*)));
}
void WebService::getRequest(const QString &urlString)
{
QUrl url(urlString);
QNetworkRequest req(url);
netMgr->get(req);
request_event_loop.exec(); // wait here until the WebService::parseNetworkResponse() slot runs
// emit finished(netMgr->get(req));
}
void WebService::parseNetworkResponse(QNetworkReply *finished)
{
qDebug() << "enter parseNetworkResponse()";
if (finished->error() != QNetworkReply::NoError)
{
qDebug() << "QNetworkReply error: " << finished->error();
emit networkError(finished->error());
}
else {
data = finished->readAll();
qDebug() << data;
}
qDebug() << "request_event_loop.exit()";
request_event_loop.exit();
qDebug() << "exit parseNetworkResponse()";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WebService web;
qDebug() << "main() getRequest()";
web.getRequest("http://www.stackoverflow.com");
qDebug() << "main() getRequest() completed";
return a.exec();
}
#include "main.moc"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.