QNetworkAccessManager multiple connect to finished signal
Hello! I tried to make multiple connections to QNetworkAccessManager finished() signal.
I have ApiHandler class which makes a request handling.
And need to call a specific function after request finished (make use of slots).
I tried to make realization as below. But always worked only one connect (which is first one) - validateTokenFinished.
Explain how to properly realize what i want.
Thanks!
userapi.h
Code:
// includes...
{
Q_OBJECT
public:
explicit UserApi
(QObject *parent
= 0);
void updateFriendList();
signals:
public slots:
void friendListUpdated(QNetworkReply* reply);
};
userapi.cpp
Code:
// includes
UserApi
::UserApi(QObject *parent
) :{
}
void UserApi::updateFriendList()
{
qDebug("UserApi::updateFriendList()");
QMap<QString, QString> m;
// ...
ApiHandler *a = new ApiHandler;
connect(a->getManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(friendListUpdated(QNetworkReply*)));
a->makeRequest("friends.get", m);
}
//! Not called at all
void UserApi::friendListUpdated(QNetworkReply* reply)
{
QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
QJsonObject getjson = j.object();
qDebug() << "UserApi::friendListUpdated()" << getjson;
reply->deleteLater();
}
toolsapi.h
Code:
// includes...
{
Q_OBJECT
public:
explicit ToolsApi
(QObject *parent
= 0);
void validateToken();
signals:
public slots:
void validateTokenFinished(QNetworkReply* reply);
};
toolsapi.cpp
Code:
// includes
ToolsApi
::ToolsApi(QObject *parent
) :{
}
void ToolsApi::validateToken()
{
qDebug("ToolsApi::validateToken()");
QMap<QString, QString> m;
// ...
ApiHandler *a = new ApiHandler;
connect(a->getManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(validateTokenFinished(QNetworkReply*)));
a->makeRequest("tools.isTokenValid", m);
}
void ToolsApi::validateTokenFinished(QNetworkReply* reply)
{
QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
QJsonObject getjson = j.object();
qDebug() << "ToolsApi::validateTokenFinished()" << getjson;
reply->deleteLater();
}
mainwindow.h
Code:
// includes...
namespace Ui {
class MainWindow;
}
{
Q_OBJECT
public:
explicit MainWindow
(QWidget *parent
= 0);
~MainWindow();
ToolsApi c;
public slots:
void on_testButton_clicked();
private:
Ui::MainWindow *ui;
};
mainwindow.cpp
Code:
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow)
{
// ...
ui->setupUi(this);
c.validateToken();
}
void MainWindow::on_testButton_clicked()
{
UserApi friends;
friends.updateFriendList();
}
And an ApiHandler class
apihandler.h
Code:
// includes...
{
Q_OBJECT
public:
explicit ApiHandler
(QObject *parent
= 0);
void makeRequest
(QString method, QMap<QString, QString> parameters
);
QNetworkAccessManager* getManager();
private:
QUrl buildCall
(QString method, QMap<QString, QString> parameters
);
QNetworkAccessManager* manager;
signals:
public slots:
void slotReadyRead();
void slotError(QNetworkReply::NetworkError error);
void slotSslErrors(QList<QSslError> errorList);
};
apihandler.cpp
Code:
// includes...
ApiHandler
::ApiHandler(QObject *parent
) :{
this->manager = new QNetworkAccessManager(this);
}
QUrl ApiHandler
::buildCall(QString method, QMap<QString, QString> parameters
) {
// ...
}
void ApiHandler
::makeRequest(QString method, QMap<QString, QString> parameters
) {
QUrl url
= this
->buildCall
(method, parameters
);
QNetworkRequest request;
request.setUrl(url);
request.setRawHeader("User-Agent", "Test Client");
QNetworkReply *reply = this->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>)));
}
void ApiHandler::slotError(QNetworkReply::NetworkError error)
{
//...
}
void ApiHandler::slotSslErrors(QList<QSslError> errorList)
{
//...
}
QNetworkAccessManager* ApiHandler::getManager()
{
return this->manager;
}
Re: QNetworkAccessManager multiple connect to finished signal
Hard to tell without studying your code a little more, but perhaps the reply has been deleted by your toolsapi.cpp line 28 before the 2nd connected slot can be executed? While using deleteLater() is a common approach, I don't believe it's documented exactly how much later the instance will be deleted and will remove all connected slots as part of the deconstruction.
Try commenting out that deleteLater() and see if your 2nd connected slot gets executed.
Re: QNetworkAccessManager multiple connect to finished signal
Hello! Thats almost all code (network communication part).
I've already tried without deleteLater() but nothing changed.
Re: QNetworkAccessManager multiple connect to finished signal
You are creating "UserApi friends" on the stack, it will be destroyed immediately after you call updateFriendsList().
Btw, a QNetworkAccessManager can handle multiple requests, you don't necessarily have to create a new one for each request.
Cheers,
_
Re: QNetworkAccessManager multiple connect to finished signal
Howdy! So i should use singleton of ApiHandler or there is a different approach (with example)?
Thanks in advance!
Re: QNetworkAccessManager multiple connect to finished signal
Quote:
Originally Posted by
anda_skoa
You are creating "UserApi friends" on the stack, it will be destroyed immediately after you call updateFriendsList().
Nice catch!
Re: QNetworkAccessManager multiple connect to finished signal
Quote:
Originally Posted by
Swiftie
Howdy! So i should use singleton of ApiHandler or there is a different approach (with example)?
Just saying you don't have to use a different instance each time.
Cheers,
_