Results 1 to 7 of 7

Thread: QNetworkAccessManager multiple connect to finished signal

  1. #1
    Join Date
    Nov 2014
    Posts
    8
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default 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
    Qt Code:
    1. // includes...
    2. class UserApi : public QObject
    3. {
    4. Q_OBJECT
    5. public:
    6. explicit UserApi(QObject *parent = 0);
    7. void updateFriendList();
    8.  
    9. signals:
    10.  
    11. public slots:
    12. void friendListUpdated(QNetworkReply* reply);
    13.  
    14. };
    To copy to clipboard, switch view to plain text mode 
    userapi.cpp
    Qt Code:
    1. // includes
    2. UserApi::UserApi(QObject *parent) :
    3. QObject(parent)
    4. {
    5. }
    6.  
    7. void UserApi::updateFriendList()
    8. {
    9. qDebug("UserApi::updateFriendList()");
    10.  
    11. QMap<QString, QString> m;
    12. // ...
    13.  
    14. ApiHandler *a = new ApiHandler;
    15.  
    16. connect(a->getManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(friendListUpdated(QNetworkReply*)));
    17.  
    18. a->makeRequest("friends.get", m);
    19. }
    20.  
    21. //! Not called at all
    22. void UserApi::friendListUpdated(QNetworkReply* reply)
    23. {
    24. QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
    25. QJsonObject getjson = j.object();
    26.  
    27.  
    28. qDebug() << "UserApi::friendListUpdated()" << getjson;
    29.  
    30. reply->deleteLater();
    31. }
    To copy to clipboard, switch view to plain text mode 

    toolsapi.h
    Qt Code:
    1. // includes...
    2. class ToolsApi : public QObject
    3. {
    4. Q_OBJECT
    5. public:
    6. explicit ToolsApi(QObject *parent = 0);
    7. void validateToken();
    8.  
    9. signals:
    10.  
    11. public slots:
    12. void validateTokenFinished(QNetworkReply* reply);
    13.  
    14. };
    To copy to clipboard, switch view to plain text mode 
    toolsapi.cpp
    Qt Code:
    1. // includes
    2. ToolsApi::ToolsApi(QObject *parent) :
    3. QObject(parent)
    4. {
    5. }
    6.  
    7. void ToolsApi::validateToken()
    8. {
    9. qDebug("ToolsApi::validateToken()");
    10.  
    11. QMap<QString, QString> m;
    12. // ...
    13.  
    14. ApiHandler *a = new ApiHandler;
    15.  
    16. connect(a->getManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(validateTokenFinished(QNetworkReply*)));
    17.  
    18. a->makeRequest("tools.isTokenValid", m);
    19. }
    20.  
    21. void ToolsApi::validateTokenFinished(QNetworkReply* reply)
    22. {
    23. QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
    24. QJsonObject getjson = j.object();
    25.  
    26. qDebug() << "ToolsApi::validateTokenFinished()" << getjson;
    27.  
    28. reply->deleteLater();
    29. }
    To copy to clipboard, switch view to plain text mode 

    mainwindow.h
    Qt Code:
    1. // includes...
    2. namespace Ui {
    3. class MainWindow;
    4. }
    5.  
    6. class MainWindow : public QMainWindow
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. explicit MainWindow(QWidget *parent = 0);
    12. ~MainWindow();
    13. ToolsApi c;
    14.  
    15. public slots:
    16. void on_testButton_clicked();
    17.  
    18. private:
    19. Ui::MainWindow *ui;
    20. };
    To copy to clipboard, switch view to plain text mode 
    mainwindow.cpp
    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. // ...
    6. ui->setupUi(this);
    7.  
    8. c.validateToken();
    9. }
    10.  
    11. void MainWindow::on_testButton_clicked()
    12. {
    13. UserApi friends;
    14.  
    15. friends.updateFriendList();
    16. }
    To copy to clipboard, switch view to plain text mode 

    And an ApiHandler class

    apihandler.h
    Qt Code:
    1. // includes...
    2. class ApiHandler : public QObject
    3. {
    4. Q_OBJECT
    5. public:
    6. explicit ApiHandler(QObject *parent = 0);
    7. void makeRequest(QString method, QMap<QString, QString> parameters);
    8. QNetworkAccessManager* getManager();
    9.  
    10. private:
    11. QUrl buildCall(QString method, QMap<QString, QString> parameters);
    12. QNetworkAccessManager* manager;
    13.  
    14. signals:
    15.  
    16. public slots:
    17. void slotReadyRead();
    18. void slotError(QNetworkReply::NetworkError error);
    19. void slotSslErrors(QList<QSslError> errorList);
    20. };
    To copy to clipboard, switch view to plain text mode 
    apihandler.cpp
    Qt Code:
    1. // includes...
    2.  
    3. ApiHandler::ApiHandler(QObject *parent) :
    4. QObject(parent)
    5. {
    6. this->manager = new QNetworkAccessManager(this);
    7. }
    8.  
    9. QUrl ApiHandler::buildCall(QString method, QMap<QString, QString> parameters)
    10. {
    11. // ...
    12. }
    13.  
    14. void ApiHandler::makeRequest(QString method, QMap<QString, QString> parameters)
    15. {
    16. QUrl url = this->buildCall(method, parameters);
    17.  
    18. QNetworkRequest request;
    19.  
    20. request.setUrl(url);
    21. request.setRawHeader("User-Agent", "Test Client");
    22.  
    23. QNetworkReply *reply = this->manager->get(request);
    24.  
    25. connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    26. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
    27. connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(slotSslErrors(QList<QSslError>)));
    28. }
    29.  
    30. void ApiHandler::slotError(QNetworkReply::NetworkError error)
    31. {
    32. //...
    33. }
    34.  
    35. void ApiHandler::slotSslErrors(QList<QSslError> errorList)
    36. {
    37. //...
    38. }
    39.  
    40. QNetworkAccessManager* ApiHandler::getManager()
    41. {
    42. return this->manager;
    43. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default 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.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  3. #3
    Join Date
    Nov 2014
    Posts
    8
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QNetworkAccessManager multiple connect to finished signal

    Hello! Thats almost all code (network communication part).

    I've already tried without deleteLater() but nothing changed.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default 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,
    _

  5. #5
    Join Date
    Nov 2014
    Posts
    8
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default 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!

  6. #6
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QNetworkAccessManager multiple connect to finished signal

    Quote Originally Posted by anda_skoa View Post
    You are creating "UserApi friends" on the stack, it will be destroyed immediately after you call updateFriendsList().
    Nice catch!
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkAccessManager multiple connect to finished signal

    Quote Originally Posted by Swiftie View Post
    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,
    _

Similar Threads

  1. QNetworkAccessManager no finished() signal emitted
    By realperson in forum Qt Programming
    Replies: 4
    Last Post: 18th January 2018, 09:42
  2. QNetworkAccessManager - finished signal (when emitted)
    By RavensAngel in forum Qt Programming
    Replies: 4
    Last Post: 16th March 2016, 21:46
  3. Replies: 7
    Last Post: 14th November 2014, 17:29
  4. Replies: 7
    Last Post: 7th August 2014, 07:43
  5. QNetworkAccessManager does not signal finished
    By lukas.zachy in forum Newbie
    Replies: 5
    Last Post: 26th January 2011, 10:05

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.