gpt4 book ai didi

c++ - QNetworkAccessManager 一个实例和连接槽

转载 作者:行者123 更新时间:2023-11-30 05:09:41 33 4
gpt4 key购买 nike

我的第一个 Qt 应用程序正在开发中。它是用于站点消息传递的桌面客户端。

Qt 文档说我只需要一个 QNetworkAccessManager 跨应用程序实例。但我也读到在 Qt 中使用单例不是一个好主意。我如何在应用程序中创建一个 QNetworkAccessManager 实例?

另一个问题是当我从其他类调用 ApiHandler 函数时如何正确连接插槽?

例如我有 ExampleApi 类,它使用 ApiHandler 的函数,在 updateMessageListmessagesListUpdated 应该被连接请求完成后更新 View 中的消息列表,但它从未调用过。

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

最佳答案

QNetworkAccessManager 片段的一个实例

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

关于c++ - QNetworkAccessManager 一个实例和连接槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46056808/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com