向Web服务发出请求,获取JSON响应并更新Qt中的GUI [英] Make get request to web service, get json response and update GUI in Qt

查看:273
本文介绍了向Web服务发出请求,获取JSON响应并更新Qt中的GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用 Qt (使用Qt Creator 4.1.0)并将数据连接到GUI 来学习 Web服务.我已经阅读了几个在线示例(最著名的是: 1 2

Trying to learn Web Services with Qt (using Qt Creator 4.1.0) and connecting data to the GUI. I have read several online examples (most notably: 1, 2 and 3) but my low coding level along with the fact that I could not find full examples that were demonstrating my needs lead me here :).

我创建了一个简单的示例,其中包含了我的所有缺点:

I have created a simple example so that contains all my shortcomings:

    每30秒
  • 向(现有)网络服务发出HTTP获取请求.
  • 然后,Web服务通过发送并接收并解析的json数据对象(请参阅下面的json示例格式)进行响应.
  • 然后, Qt会将所有已解析的json数据显示在一个简单的GUI上(有关这种GUI的外观,请参见下文.
  • make an HTTP get request to a (existing) web service every 30 seconds.
  • The web service then responds by sending a json data object (see below for such a json example format) which we receive and parse.
  • Then, the Qt will display all the parsed json data onto a simple GUI (see below for how such a GUI looks like.

json数据格式-示例:

{
    "city": "London",
    "time": "16:42",
    "unit_data": 
        [
            {
                "unit_data_id": "ABC123",
                "unit_data_number": "21"
            }
        ]
}

我简单的Qt GUI设计(由Qt Creator创建)显示所有提取的解析数据:

My simple Qt GUI design (made in Qt Creator) displaying all the fetched parsed data:

我非常感谢任何完整的代码示例,这些示例显示了我们如何向Web服务发出请求,然后如何获取json响应.最后,如何在Qt中连接GUI以便在收到数据后立即显示它们.

I would really appreciate any full code example that show how we can make a request to a web service and then how to fetch the json response. Finally, how to connect the GUI in Qt to display this data as soon as they are received.

我刚刚开始研究这一领域,我需要一个简单的完整代码示例来使我前进.

I am just starting studying this area and I am in need of a simple full code example to get me going.

推荐答案

下面是一个完整的示例,说明如何使用

Here is a fully working example on how to send a GET request with parameters to a web service using QNetworkAccessManager and parse the JSON response using QJsonDocument.

在示例中,我向http://uinames.com/发送请求,其响应以以下格式用JSON编码:

In the example, I am sending a request to http://uinames.com/ whose responses are encoded in JSON in the following format:

{
    "name":"John",
    "surname":"Doe",
    "gender":"male",
    "region":"United States"
}

我正在解析JSON响应并将其显示在GUI中.

I am parsing the JSON response and displaying it in a GUI.

#include <QtWidgets>
#include <QtNetwork>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //setup GUI (you could be doing this in the designer)
    QWidget widget;
    QFormLayout layout(&widget);
    QLineEdit lineEditName;
    QLineEdit lineEditGender;
    QLineEdit lineEditRegion;
    auto edits = {&lineEditName, &lineEditGender, &lineEditRegion};
    for(auto edit : edits) edit->setReadOnly(true);
    layout.addRow("Name:", &lineEditName);
    layout.addRow("Gender:", &lineEditGender);
    layout.addRow("Region:", &lineEditRegion);
    QPushButton button("Get Name");
    layout.addRow(&button);

    //send request to uinames API
    QNetworkAccessManager networkManager;
    QObject::connect(&networkManager, &QNetworkAccessManager::finished,
                     [&](QNetworkReply* reply){
        //this lambda is called when the reply is received
        //it can be a slot in your GUI window class
        //check for errors
        if(reply->error() != QNetworkReply::NoError){
            for(auto edit : edits) edit->setText("Error");
            networkManager.clearAccessCache();
        } else {
            //parse the reply JSON and display result in the UI
            QJsonObject jsonObject= QJsonDocument::fromJson(reply->readAll()).object();
            QString fullName= jsonObject["name"].toString();
            fullName.append(" ");
            fullName.append(jsonObject["surname"].toString());
            lineEditName.setText(fullName);
            lineEditGender.setText(jsonObject["gender"].toString());
            lineEditRegion.setText(jsonObject["region"].toString());
        }
        button.setEnabled(true);
        reply->deleteLater();
    });
    //url parameters
    QUrlQuery query;
    query.addQueryItem("amount", "1");
    query.addQueryItem("region", "United States");
    QUrl url("http://uinames.com/api/");
    url.setQuery(query);
    QNetworkRequest networkRequest(url);
    //send GET request when the button is clicked
    QObject::connect(&button, &QPushButton::clicked, [&](){
        networkManager.get(networkRequest);
        button.setEnabled(false);
        for(auto edit : edits) edit->setText("Loading. . .");
    });

    widget.show();
    return a.exec();
}

由于您询问如何使用 QTimer 要每隔一分钟触发一次更新,请使用以下代码替换上面代码中对clicked按钮的connect信号调用:

Since you asked about how to use a QTimer to trigger the update every one minute, replace the connect call of the button clicked signal from the code above with something like this:

QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&](){
    networkManager.get(networkRequest);
    button.setEnabled(false);
    for(auto edit : edits) edit->setText("Loading. . .");
});
timer.start(60000); //60000 msecs = 60 secs

如注释中所述,如果在窗口类的构造函数中使用它,则必须确保此处的networkManagernetworkRequest,GUI组件和timer保持活动状态.您的窗口对象正在运行.因此,您可以选择将它们分配在堆中或作为类成员.

As noted in comments, if you are using this in your window class's constructor, you have to make sure that the networkManager, networkRequest, the GUI components, and the timer here are kept alive as long as your window object is running. So, you may choose to allocate them in the heap or as class members.

这篇关于向Web服务发出请求,获取JSON响应并更新Qt中的GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆