qnetworkAccessManager一个实例并连接插槽



我在开发中有第一个QT应用程序。这是用于网站消息的桌面客户端。

QT文档说我只需要一个实例 qnetworkAccessManager accross应用程序。但是我还读到,使用QT的单例并不是一个好主意。我如何在应用程序上制作一个实例 qnetworkAccessManager

另一个问题是如何在我调用 apihandler 函数时如何正确连接插槽?

例如,我有使用 apihandler exippleapi 类请求完成以更新消息列表后,但它从未打电话。

exppleapi.h

...
#include "apihandler.h"
class ExampleApi : public QObject
{
    Q_OBJECT
public:
    explicit ExampleApi(QObject *parent = 0);
    void updateMessagesList();
signals:
public slots:
    void messagesListUpdated(QNetworkReply* reply);
};

exkpleapi.cpp

ExampleApi::ExampleApi(QObject *parent) :
    QObject(parent)
{
}
void ExampleApi::updateMessagesList()
{
    QMap<QString, QString> m;
    m["user_id"] = ConfigParser::settings.value(USER_ID).toString();
    QNetworkAccessManager nam;
    ApiHandler a(&nam);
    // Connect a slot
    connect(a.getManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(messagesListUpdated(QNetworkReply*)));
    a.makeRequest("messages.get", m);
}
void ExampleApi::messagesListUpdated(QNetworkReply* reply)
{
    QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
    QJsonObject getjson = j.object();
    qDebug() << "ExampleApi::messagesListUpdated()" << getjson;
    reply->deleteLater();
    // ...
}

apihandler.h

class ApiHandler : public QObject
{
    Q_OBJECT
public:
    explicit ApiHandler(QNetworkAccessManager *nam, QObject *parent = 0);
    ~ApiHandler();
    QNetworkReply* makeRequest(QString method, QMap<QString, QString> parameters);
    QNetworkAccessManager* getManager();
private:
    QUrl buildCall(QString method, QMap<QString, QString> parameters);
    QNetworkAccessManager* manager;
signals:
public slots:
    void replyFinished(QNetworkReply* reply);
    void slotReadyRead();
    void slotError(QNetworkReply::NetworkError error);
    void slotSslErrors(QList<QSslError> errorList);
};

apihandler.cpp

#include "apihandler.h"
ApiHandler::ApiHandler(QNetworkAccessManager *nam, QObject *parent) :
    QObject(parent), manager(nam)
{
    Q_ASSERT(manager);
}
ApiHandler::~ApiHandler()
{
    manager->deleteLater();
}
QUrl ApiHandler::buildCall(QString method, QMap<QString, QString> parameters)
{
    QUrl url = QUrl(API_URL + method);
    QUrlQuery query;
    ConfigParser c;
    // Append first access_token
    query.addQueryItem("access_token", c.settings.value(ACCESS_TOKEN_KEY).toString());
    if (!parameters.isEmpty()) {
        QMapIterator<QString, QString> i(parameters);
        while (i.hasNext()) {
            i.next();
            query.addQueryItem(i.key(), i.value());
        }
    }
    url.setQuery(query.query());
    return url;
}
QNetworkReply* ApiHandler::makeRequest(QString method, QMap<QString, QString> parameters)
{
    QUrl url = this->buildCall(method, parameters);
    //qDebug() << "ApiHandler::makeRequest: " << url;
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    QNetworkRequest request;
    request.setUrl(url);
    request.setRawHeader("User-Agent", "Site-Client");
    QNetworkReply *reply = manager->get(request);
    connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
    connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(slotSslErrors(QList<QSslError>)));
    return reply;
}
void ApiHandler::replyFinished(QNetworkReply* reply)
{
    qDebug() << "ApiHandler::replyFinished:" << reply->url();
    QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
    if (j.isEmpty()) {
        // throw error
        qDebug("ApiHandler::replyFinished(...) j.isEmpty :(");
    } else {
        qDebug() << "ApiHandler::replyFinished(...)" << j;
    }
    reply->deleteLater();
}
void ApiHandler::slotReadyRead()
{
    //qDebug("slotReadyRead");
}
void ApiHandler::slotError(QNetworkReply::NetworkError error)
{
    qWarning() << "raised error:" << error;
}
void ApiHandler::slotSslErrors(QList<QSslError> errorList)
{
    qWarning() << "raised sslErrors" << errorList;
}
QNetworkAccessManager* ApiHandler::getManager()
{
    return this->manager;
}

qnetworkAccessManager smippet的一个实例

QNetworkAccessManager* getManager() {
    static QNetworkAccessManager* nam = new QNetworkAccessManager;
    return nam;
}

最新更新