为什么这个Qt信号永远不会被发射?

时间:2013-10-10 20:44:52

标签: c++ qt

我正在尝试从网页中获取数据,但信号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永远不会按预期分配值。

1 个答案:

答案 0 :(得分:1)

您没有将网址传递给您创建的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()的{​​{1}},其中包含相应的网址
  • WebService::getRequest()添加到#include "main.moc"文件的末尾,以便qmake将其“moc-ify”正确地作为单个自包含的.cpp文件
  • 在问题的答案
  • 中做出了上述修复
  • 在错误案例中添加了main.cpp输出

最后需要做的是在项目的.pro文件中添加qDebug(),以便将Qt网络模块添加到链接步骤和标题搜索路径中。


2013年10月15日更新

从您的评论中,您希望QT += network调用是同步的。我添加了另一个版本的示例程序,它将在QNetworkAccessManager::get()中阻止,直到收到请求的WebService::getRequest()信号。请注意,此示例在错误处理方面执行不多,如果netwrok请求未能及时完成,则可能执行得非常糟糕。除了示例或学习代码之外,任何其他内容都需要适当地处理错误和超时。

此示例中的基本思想是异步Qt网络模型中发出的信号由框架的事件循环驱动。因此,当发出请求时,会创建一个新的“嵌套”事件循环,finished函数执行该循环(并保持在那里),直到WebService::getRequest()信号的处理程序告诉事件循环退出。

finished