Qt6 QML Book/网络设置/HTTP请求

HTTP Requests

HTTP请求

An HTTP request is in Qt typically done using QNetworkRequest and QNetworkReply from the c++ site and then the response would be pushed using the Qt/C++ integration into the QML space. So we try to push the envelope here a little bit to use the current tools Qt Quick gives us to communicate with a network endpoint. For this, we use a helper object to make an HTTP request, response cycle. It comes in the form of the javascript XMLHttpRequest object.

HTTP请求在QT中通常使用C++库的QNetworkRequestQNetworkReply来完成,然后使用Qt/C++集成将响应推送到QML空间中。因此,我们尝试在这里使用Qt Quick为我们提供的与网络端点通信的当前工具来通信。为此,我们使用一个helper对象来发出HTTP请求,即循环响应。它以javascript XMLHttpRequest对象的形式出现。

The XMLHttpRequest object allows the user to register a response handler function and a URL. A request can be sent using one of the HTTP verbs (get, post, put, delete, …) to make the request. When the response arrives the handler function is called. The handler function is called several times. Every-time the request state has changed (for example headers have arrived or request is done).

XMLHttpRequest对象允许用户注册响应处理器函数和URL。可以使用HTTP关键字之一(get、post、put、delete等)发送请求以发出请求。当响应到达时,将调用处理器函数。处理器函数被调用了几次。每次请求状态发生更改时(例如,标头已到达或请求已完成)。

Here a short example:

下面是一个简短的例子:

function request() {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
            print('HEADERS_RECEIVED');
        } else if(xhr.readyState === XMLHttpRequest.DONE) {
            print('DONE');
        }
    }
    xhr.open("GET", "http://example.com");
    xhr.send();
}

For a response, you can get the XML format or just the raw text. It is possible to iterate over the resulting XML but more commonly used is the raw text nowadays for a JSON formatted response. The JSON document will be used to convert text to a JS object using JSON.parse(text).

对于响应,可以获取XML格式,也可以只获取原始文本。可以对生成的XML进行迭代,但现在更常用的是JSON格式响应的原始文本。JSON文档将使用JSON.parse(text)将文本转换为JS对象。

/* ... */
} else if(xhr.readyState === XMLHttpRequest.DONE) {
    var object = JSON.parse(xhr.responseText.toString());
    print(JSON.stringify(object, null, 2));
}

In the response handler, we access the raw response text and convert it into a javascript object. This JSON object is now a valid JS object (in javascript an object can be an object or an array).

在响应处理器中,我们访问原始响应文本并将其转换为javascript对象。这个JSON对象现在是一个有效的JS对象(在javascript中,对象可以是对象或数组)。

TIP

It seems the toString() conversion first makes the code more stable. Without the explicit conversion, I had several times parser errors. Not sure what the cause it.

似乎toString()转换首先使代码更稳定。如果没有显式转换,我会有好几次语法分析器错误。不知道是什么原因造成的。

Flickr Calls

Flickr调用

Let us have a look on a more real-world example. A typical example is to use the Flickr service to retrieve a public feed of the newly uploaded pictures. For this, we can use the http://api.flickr.com/services/feeds/photos_public.gne URL. Unfortunately, it returns by default an XML stream, which could be easily parsed by the XmlListModel in qml. For the sake of the example, we would like to concentrate on JSON data. To become a clean JSON response we need to attach some parameters to the request: http://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1. This will return a JSON response without the JSON callback.

让我们看一个更真实的例子。一个典型的例子是使用Flickr服务检索新上传图片的公共提要。为此,我们可以使用http://api.flickr.com/services/feeds/photos_public.gne网址。不幸的是,它默认返回一个XML流,qml中的XmlListModel可以轻松解析该流。为了这个例子,我们想集中讨论JSON数据。要成为干净的JSON响应,我们需要在请求中附加一些参数:http://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1.这将返回一个不带JSON回调的JSON响应。

TIP

A JSON callback wraps the JSON response into a function call. This is a shortcut used on HTML programming where a script tag is used to make a JSON request. The response will trigger a local function defined by the callback. There is no mechanism which works with JSON callbacks in QML.

JSON回调将JSON响应打包为函数调用。这是HTML编程中使用的快捷方式,其中使用脚本标记发出JSON请求。响应将触发回调函数定义的本地函数。QML中没有任何机制可以处理JSON回调。

Let us first examine the response by using curl:

让我们首先使用curl检查响应:

curl "http://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1&tags=munich"

The response will be something like this:

响应是这样的:

{
    "title": "Recent Uploads tagged munich",
    ...
    "items": [
        {
        "title": "Candle lit dinner in Munich",
        "media": {"m":"http://farm8.staticflickr.com/7313/11444882743_2f5f87169f_m.jpg"},
        ...
        },{
        "title": "Munich after sunset: a train full of \"must haves\" =",
        "media": {"m":"http://farm8.staticflickr.com/7394/11443414206_a462c80e83_m.jpg"},
        ...
        }
    ]
    ...
}

The returned JSON document has a defined structure. An object which has a title and an items property. Where the title is a string and items is an array of objects. When converting this text into a JSON document you can access the individual entries, as it is a valid JS object/array structure.

返回的JSON文档具有已定义的结构。具有标题title和items属性的对象。其中,标题是字符串,项是对象数组。当将此文本转换为JSON文档时,您可以访问各个条目,因为它是一个有效的JS对象/数组结构。

// JS code
obj = JSON.parse(response);
print(obj.title) // => "Recent Uploads tagged munich"
for(var i=0; i<obj.items.length; i++) {
    // iterate of the items array entries
    print(obj.items[i].title) // title of picture
    print(obj.items[i].media.m) // url of thumbnail
}

As a valid JS array, we can use the obj.items array also as a model for a list view. We will try to accomplish this now. First, we need to retrieve the response and convert it into a valid JS object. And then we can just set the response.items property as a model to a list view.

作为一个有效的JS数组,我们可以使用obj.items数组也可以作为列表视图的模型。我们现在将努力实现这一目标。首先,我们需要检索响应并将其转换为有效的JS对象。然后我们可以设置response.items属性作为列表视图的模型。

function request() {
    const xhr = new XMLHttpRequest()
    xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
            print('HEADERS_RECEIVED')
        } else if(xhr.readyState === XMLHttpRequest.DONE) {
            print('DONE')
            const response = JSON.parse(xhr.responseText.toString())
            // Set JS object as model for listview
            view.model = response.items
        }
    }
    xhr.open("GET", "http://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1&tags=munich")
    xhr.send()
}

Here is the full source code, where we create the request when the component is loaded. The request response is then used as the model for our simple list view.

下面是完整的源代码,我们在加载组件时在其中创建请求。然后,请求-响应被用作简单列表视图的模型。

import QtQuick

Rectangle {
    id: root

    width: 320
    height: 480

    ListView {
        id: view
        anchors.fill: parent
        delegate: Thumbnail {
            required property var modelData
            width: view.width
            text: modelData.title
            iconSource: modelData.media.m
        }
    }

    function request() {
        const xhr = new XMLHttpRequest()
        xhr.onreadystatechange = function() {
            if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
                print('HEADERS_RECEIVED')
            } else if(xhr.readyState === XMLHttpRequest.DONE) {
                print('DONE')
                const response = JSON.parse(xhr.responseText.toString())
                // Set JS object as model for listview
                view.model = response.items
            }
        }
        xhr.open("GET", "http://api.flickr.com/services/feeds/photos_public.gne?format=json&nojsoncallback=1&tags=munich")
        xhr.send()
    }

    Component.onCompleted: {
        root.request()
    }
}

When the document is fully loaded ( Component.onCompleted ) we request the latest feed content from Flickr. On arrival, we parse the JSON response and set the items array as the model for our view. The list view has a delegate, which displays the thumbnail icon and the title text in a row.

当文档完全加载(Component.onCompleted)时,我们从Flickr请求最新的提要内容。到达时,我们解析JSON响应,并将items数组设置为视图的模型。列表视图有一个委托,它在一行中显示缩略图图标和标题文本。

The other option would be to have a placeholder ListModel and append each item onto the list model. To support larger models it is required to support pagination (e.g page 1 of 10) and lazy content retrieval.

另一个选项是使用占位符ListModel,并将每个项目附加到列表模型中。为了支持更大的模型,需要支持分页(例如第1页,共10页)和延迟内容检索。

示例源码下载

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在配置QT6的QML环境时,您可以遵循以下步骤: 1. 确保您已经安装了QT6的开发环境。您可以从QT官方网站下载并安装最新版本的QT。 2. 在项目文件(例如myproject.pro)中,添加需要使用的模块。对于QML应用程序,您需要添加QtQuick和QtQml模块到QT变量中,如下所示: ``` QT += qml quick ``` 3. 确保您的项目文件正确指定了源文件。在SOURCES变量中,添加您的main.cpp文件或其他需要编译的源文件,如下所示: ``` SOURCES += main.cpp ``` 4. 使用所选的构建系统来构建您的项目。在QT6中,您可以选择使用CMake作为构建系统。确保设置正确的构建配置和目标平台,并运行构建命令来生成可执行文件。 注意,QT6中不再使用qmake作为默认的构建系统,而是采用了CMake。您可以在项目文件中切换到使用CMake,或者使用QT Creator来配置和构建您的项目。 希望这些信息对您有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Qt6 QML Book/Qt C++/构建系统](https://blog.csdn.net/aggs1990/article/details/122769759)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值