QNetworkReply 不触发

Posted

技术标签:

【中文标题】QNetworkReply 不触发【英文标题】:QNetworkReply Doesn't Trigger 【发布时间】:2013-09-29 02:06:13 【问题描述】:

我是 C++ 和 Qt 的新手,所以很自然地遇到了麻烦。我正在尝试创建一个与连接到 URL 并接收 JSON 响应的 MainWindow 分开的类。但是,使用 QObject::connect 后,程序并没有连接到 SLOT 程序。

这是我目前的代码(jsonhandle.h):

#ifndef JSONHANDLE_H
#define JSONHANDLE_H

#include <string>
#include <QObject>
#include <QJsonObject>
#include <QtNetwork/QNetworkReply>

using std::string;

class jsonhandle: public QObject
    Q_OBJECT

public:
    jsonhandle(string url);
    void sendRequest();
    void addArg(string name, string value);
    void clearArg();
    QJsonObject getResponse();

public slots:
    void replyFinished(QNetworkReply * reply);

private:
    ////////////////////////////////////////////////////////////////////////////////////////////
    bool gotResponse;                       //Determines whether or not a response was obtained.
    string url;                             //The URL where the JSON request takes place.
    int size;                               //The number of parameters.
    string *param;                          //The array containing arguments.
    int maxSize;                            //Keeps track of the top size of the array.
    const int DEFAULT = 4;                  //The default value of the parameter array.
    QJsonObject *response;                   //The object containing the JSON data.
    ////////////////////////////////////////////////////////////////////////////////////////////

    void expandArray();                     //Expands the parameter array.
;

#endif // JSONHANDLE_H

jsonhandle.cpp:

#include "jsonhandle.h"
#include <string>
#include <iostream>
#include <QJsonDocument>
#include <QJsonObject>
#include <QString>
#include <QUrl>
#include <QUrlQuery>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QDebug>

using std::string;

jsonhandle::jsonhandle(string url)
    //Gets the url and argument list passed to the json handler.
    this->url = url;
    this->size = 0;
    this->maxSize = DEFAULT;
    this->gotResponse = false;
    this->response = new QJsonObject();

    //Now, creates the paramater array.
    this->param = new string[DEFAULT];


void jsonhandle::addArg(string name, string value)
    //Checks to see if the array is full.
    if (size >= maxSize)
        //The array has to be expanded.
        expandArray();
    

    //Now, inserts the name and parameter into param.
    param[size++] = name;
    param[size++] = value;


void jsonhandle::expandArray()
    //First gets the size of the array.
    int newSize = (this->size) * 2;

    //Creates a new array with double the size.
    string *newArr = new string[newSize];

    //Finally, populates the new array with the parameters.
    std::copy(param, param + this-> size, newArr);

    //Finally deletes the original param array.
    delete[] param;
    param = newArr;

    //Finally, updates max count.
    maxSize *= 2;


void jsonhandle::clearArg()
    //Clears the counters.
    this->maxSize = DEFAULT;
    this->size = 0;

    //Deletes the param array off the stack.
    delete[] this->param;
    this->param = new string[DEFAULT];


void jsonhandle::sendRequest()
    //The network manager will post and recieve our HTTP requests.
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);

    QObject::connect(manager, SIGNAL(finished(QNetworkReply *)), SLOT(replyFinished(QNetworkReply *)));

    //The host of the webservice.
    QString acceptedURL = QString::fromStdString(this->url);
    QUrl url(acceptedURL);

    //Sets up the post data request.
    QNetworkRequest req;
    req.setUrl(acceptedURL);
    req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    //Now, interacts with the data and gets all the additional parameters.
    QUrlQuery query(url);
    for (int i = 0; i < size; i += 2)
        query.addQueryItem(QString::fromStdString(param[i]), QString::fromStdString(param[i + 1]));
    
    url.setQuery(query);

    //Update the request with the new query information.
    req.setUrl(url);

    // DEBUG TIP:
    //   The following line will allow you print the full HTTP request that will be made
    //   You can enter it directly into a browser, and the JSON object returned will be shown
    //   This is why iostream is included in this file
    std::cout<< url.toString().toStdString()<<std::endl;

    //Post the request
    manager->post(req, url.toEncoded());


void jsonhandle::replyFinished(QNetworkReply * reply)
    if (reply->error() != QNetworkReply::NoError)
        // A communication error has occurred
        std::cout << "Error in connecting." << std::endl;
        this->gotResponse = false;
    

    //We read the JSON response into a QJsonObject
    QJsonObject obj = QJsonDocument::fromJson(reply->readAll()).object();
    this->response = &(obj);
    this->gotResponse = true;


QJsonObject jsonhandle::getResponse()
     //Sees if a response was obtained from JSON
    if (gotResponse == false)
        response->insert("error",QJsonValue::Null);
    

    return *response;

如果你们解决了什么问题,请告诉我。

【问题讨论】:

你怎么知道replyFinished函数没有运行?你的程序可能会崩溃吗? 【参考方案1】:

更好的连接方式

QNetworkReply *reply = manager->post (request, data);
connect (reply,
    SIGNAL (finished ()),
    this,
    SLOT (handleReplyFinished ()));

【讨论】:

以上是关于QNetworkReply 不触发的主要内容,如果未能解决你的问题,请参考以下文章

QNetworkReply 返回不完整的 XML 数据

12.4.3 实现网络文件下载

QNetworkReply 等待完成

QNetworkReply - 建立连接,写入第一个字节等

QEventLoop 没有同步等待 QNetworkReply 完成

连接丢失时未检测到 QNetworkReply 错误信号