QNetworkAccessManager one instance and connecting slots

匿名 (未验证) 提交于 2019-12-03 01:36:02

问题:

I have my first Qt application in development. It's a desktop client for site messaging.

Qt documentation says that i need to have only one instance of QNetworkAccessManager accross application. But i also read that using of singletons with Qt isn't a good idea. How i can make one instance of QNetworkAccessManager across app?

Another question is how to properly connect slots while i call ApiHandler functions from other classes?

For example i have ExampleApi class which uses functions of ApiHandler, in updateMessageList slot messagesListUpdated should be connected after request finished to update message list in view, but it never called.

ExampleApi.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);  };

ExampleApi.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; }

回答1:

One instance of QNetworkAccessManager snippet

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!