Why the SLOT method not triggered? [solved]



  • I am trying to do a simple programming to parse JSON message value from web to Qt Quick.

    The JSON message would like to parse:

    [
        {
             "id": 2,
             "name": "yahoo",
             "link": "http://www.yahoo.com/",
             "created_by": "superadmin",
             "create_time": "2015-03-12 14:45:21"
        },
        {
             "id": 3,
             "name": "Google",
             "link": "http://www.google.com/",
             "created_by": "superadmin",
             "create_time": "2015-03-12 14:45:41"
        },
        {
             "id": 4,
             "name": "PS",
             "link": "http://www.playstation.com",
             "created_by": "superadmin",
             "create_time": "2015-03-24 11:57:21"
        }
    ]
    

    The following is the Qt code main.cpp to try to parse these data:

    #include <QGuiApplication>
    #include <QStringList>
    #include <QNetworkReply>
    #include <QNetworkRequest>
    #include <QNetworkAccessManager>
    #include <QtScript/QScriptEngine>
    #include <QtScript/QScriptValueIterator>
    #include <QJsonDocument>
    #include <QJsonObject>
    #include <QJsonArray>
    #include <qqmlengine.h>
    #include <qqmlcontext.h>
    #include <qqml.h>
    #include <QtQuick/qquickitem.h>
    #include <QtQuick/qquickview.h>
    #include <main.h>
    
    
    
    QStringList Jsondata::datalistmethod() {
    
       return datalist;
    }
    
    
    void Jsondata::onResult(QNetworkReply* reply)
    {
        
        QString data = (QString) reply->readAll();
    
    
        QJsonDocument jsonResponse = QJsonDocument::fromJson(data.toUtf8());
        QJsonObject jsonObject = jsonResponse.object();
    
    
        foreach (const QJsonValue & value, jsonObject) {
            QJsonObject obj = value.toObject();
            datalist.append(obj["name"].toString());
            datalist.append(obj["link"].toString());
        }
    }
    
    int main(int argc, char ** argv)
    {
        QGuiApplication app(argc, argv);
        Jsondata jsondata;
        // Now parse this JSON according to your needs !
       QNetworkAccessManager networkManager;
       networkManager.setNetworkAccessible(QNetworkAccessManager::Accessible);
    
       QUrl url("http://**/api/web/v1/links");
       QNetworkRequest request;
       request.setUrl(url);
    
       Jsondata::connect(&networkManager, SIGNAL(finished(QNetworkReply*)), &jsondata, SLOT(onResult(QNetworkReply*)));
        networkManager.get(request);   // GET
    
        QStringList datalist;
        datalist = jsondata.datalistmethod();
    
        QQuickView view;
        QQmlContext *ctxt = view.rootContext();
        ctxt->setContextProperty("myModel", QVariant::fromValue(datalist));
    
        view.setSource(QUrl("qrc:main.qml"));
        view.show();
    
        return app.exec();
    }
    

    main.h

    #ifndef MAIN
    #define MAIN
    #include <QObject>
    #include <QNetworkReply>
    #include <QStringList>
    class Jsondata : public QObject {
        Q_OBJECT
        QStringList datalist;
    public slots:
        void onResult (QNetworkReply*);
    public:
        QStringList datalistmethod();
    };
    #endif // MAIN
    

    main.qml

    import QtQuick 2.0
    //![0]
    
    ListView {
        width: 100; height: 100
    
        model: myModel
        delegate: Rectangle {
            height: 25
            width: 100
            Text { text: modelData }
        }
    }
    //![0]
    

    Results in:
    onResult still not called. so no datalist returned

    I don't have knowledge on this QObject::connect and don't know what wrong. I would appreciate it if you could help me to fix this bug. Thank you.



  • Your problem is most likely that you try to use SIGNAL/SLOTS before you have called exec(). Signals and Slots need an event loop to work.

    Try calling networkManager.get(...) from code that is run after exec().



  • I finally found a method to solve the problem. The following is the code snippet.

    main.cpp

    #include <QGuiApplication>
    #include <QStringList>
    #include <qqmlengine.h>
    #include <qqmlcontext.h>
    #include <qqml.h>
    #include <QtQuick/qquickitem.h>
    #include <QtQuick/qquickview.h>
    #include <jsondata.h>
    
    int main(int argc, char ** argv)
    {
        QGuiApplication app(argc, argv);
        QStringList datalist;
        Jsondata jsondata;
        jsondata.datalistmethod();
        datalist = jsondata.datalist;
    
        QQuickView view;
        QQmlContext *ctxt = view.rootContext();
        ctxt->setContextProperty("myModel", QVariant::fromValue(datalist));
        view.setSource(QUrl("qrc:main.qml"));
        view.show();
    
        return app.exec();
    
    }
    

    jsondata.h

    #ifndef JSONDATA_H
    #define JSONDATA_H
    #include <QObject>
    #include <QNetworkReply>
    #include <QStringList>
    #include <QNetworkAccessManager>
    class Jsondata : public QObject {
        Q_OBJECT
    public:
        QStringList datalist;
        explicit Jsondata(QObject *parent =0);
        void datalistmethod();
    public slots:
        void onResult (QNetworkReply*);
    
    private:
        QNetworkAccessManager *manager;
    };
    

    jsondata.cpp

    #include "jsondata.h"
    #include <QNetworkReply>
    #include <QNetworkRequest>
    #include <QNetworkAccessManager>
    #include <QJsonDocument>
    #include <QJsonObject>
    #include <QJsonArray>
    #include <QEventLoop>
    #include <QtQuick/qquickitem.h>
    #include <QtQuick/qquickview.h>
    #include <QTimer>
    #include <qqmlengine.h>
    #include <qqmlcontext.h>
    #include <qqml.h>
    
    Jsondata::Jsondata(QObject *parent) :
        QObject(parent)
    {
    
    }
    
    
    void Jsondata::datalistmethod() {
        // Now parse this JSON according to your needs !
       manager = new QNetworkAccessManager(this);
    
       manager->setNetworkAccessible(QNetworkAccessManager::Accessible);
        QNetworkRequest request;
       QEventLoop eventloop;
       QUrl url("http://***/api/web/v1/links");
        request.setUrl(url);
         QNetworkReply *reply = manager->get(request);
       connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
       eventloop.exec();
       onResult(reply);
    
    }
    
    
    void Jsondata::onResult(QNetworkReply* reply)
    {
        QString data = (QString) reply->readAll();
        qDebug() << "Response:" << data;
        QJsonDocument jsonResponse = QJsonDocument::fromJson(data.toUtf8());
        QJsonArray jsonArray = jsonResponse.array();
        foreach (const QJsonValue & value, jsonArray) {
            QJsonObject obj = value.toObject();
            datalist.append(obj["name"].toString());
            datalist.append(obj["link"].toString());
        }
    }
    

    By adding event loop, the datalist method will wait for the onResult method completed to execute next line of code. This is using the example of string list model. If anyone feel it useful for reference, please +1 my post. Thank you. ^^


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.