Ich habe meine erste Qt-Anwendung in Entwicklung. Es ist ein Desktop-Client für Site-Messaging.QNetworkAccessManager eine Instanz und verbinden Steckplätze
Qt Dokumentation sagt, dass ich nur eine Instanz von QNetworkAccessManager über Anwendung haben muss. Aber ich lese auch, dass die Verwendung von Singletons mit Qt keine gute Idee ist. Wie kann ich eine Instanz von QNetworkAccessManager über App machen?
Eine andere Frage ist, wie man Schlitze richtig verbindet, während ich ApiHandler Funktionen von anderen Klassen nenne?
Zum Beispiel habe ich ExampleApi Klasse, die Funktionen von ApiHandler verwendet, in updateMessageList Schlitz messagesListUpdated angeschlossen werden sollte nach Wunsch im Hinblick auf aktualisieren Nachrichtenliste fertig, aber es nie genannt.
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;
}
Ihr Manager den Bereich verlässt, bevor das Ergebnis empfangen wird. – m7913d
Die Lösung kann die gleiche wie mit 'QCoreApplication' und' qApp' sein: Ja, es ist ein Singleton, aber es ist ein Singleton, dessen Lebensdauer Sie vollständig kontrollieren. –