Qt6 QML Book/Qt for MCUs/使用模型

Working with Models

使用模型

In Qt Quick Ultralite, it is possible to create models in QML using the ListModel element. It is also possible, and a bit more interesting, to create models from C++. This lets you expose lists of data from C++ to QML and to instantiate user interface elements for each item of the list. The setup is very similar to the ordinary Qt Quick, but the base classes and interfaces are more limited.

在Qt Quick Ultralite中,可以使用ListModel元素在QML中创建模型。从C++中创建模型也是可能的,而且更有趣。这样,您就可以从C++到QML暴露数据列表,并为列表的每个项目实例化用户界面元素。该设置与普通的Qt-Quick非常相似,但基类和接口更有限。

In this chapter we will create a list of cities in Europe, listing the name of the city and the country in which the city is located. The cities will be shown in a ListView as shown below:

在本章中,我们将创建欧洲城市列表,列出城市名称和城市所在国家。城市将显示在列表视图ListView中,如下所示:

The C++

To create a model in Qt Quick Ultralite, the first thing we need to do is to define a struct with the data of each list item. For this struct, we also need to provide a == operator. This is what we do with the CityData struct shown below. Notice that we use std::string rather than QString in Qt Quick Ultralite. The assumption is that UTF-8 encoding is used.

要在Qt Quick Ultralite中创建模型,我们需要做的第一件事是用每个列表项的数据定义一个结构体。对于这个结构体,我们还需要提供一个==运算符。这就是我们对下面显示的CityData结构体所做的。请注意,我们在Qt Quick Ultralite中使用std::string而不是QString。假设使用UTF-8编码。

#include <string>

struct CityData
{
    std::string name;
    std::string country;
};

inline bool operator==(const CityData &l, const CityData &r)
{
    return l.name == r.name && l.country == r.country;
}

Once the data type has been prepared, we declare the CityModel struct, inheriting from Qul::ListModel. This lets us define a model that can be accessed from QML. We must implement the count and data methods, which are similar, but not identical to, the corresponding methods from the QAbstractListModel class. We also use the `CMake macro qul_target_generate_interfaces to make the types available to QML.

一旦准备好数据类型,我们就声明CityModel结构体,它继承自Qul::ListModel。这让我们可以定义一个可以从QML访问的模型。我们必须实现count和data方法,它们与QAbstractListModel类中的相应方法类似,但不完全相同。我们还使用CMake宏ul_target_generate_interfaces,使类型可供QML使用。

#include <qul/model.h>
#include <platforminterface/allocator.h>

struct CityModel : Qul::ListModel<CityData>
{
private:
    Qul::PlatformInterface::Vector<CityData> m_data;

public:
    CityModel();

    int count() const override { return m_data.size(); }
    CityData data(int index) const override { return m_data[index]; }
};

We also implement a constructor for the CityModel struct that populates the m_data vector with data.

我们还为CityModel结构体实现了一个构造函数,用数据填充m_data向量。

#include "citymodel.h"

CityModel::CityModel()
{
    m_data.push_back(CityData {"Berlin", "Germany"});
    m_data.push_back(CityData {"Copenhagen", "Denmark"});
    m_data.push_back(CityData {"Helsinki", "Finland"});
    m_data.push_back(CityData {"London", "England"});
    m_data.push_back(CityData {"Oslo", "Norway"});
    m_data.push_back(CityData {"Paris", "France"});
    m_data.push_back(CityData {"Stockholm", "Sweden"});
}

The QML

In the example, we show the model as a scrollable list, as shown below.

在本例中,我们将模型显示为可滚动列表,如下所示。

The QML code is shown in its entirety below:

QML代码如下所示:

import QtQuick 2.0

Rectangle {
    width: 480
    height: 272

    CityModel {
        id: cityModel
    }

    Component {
        id: cityDelegate

        Item {
            width: 480
            height: 45

            Column {
                spacing: 2
                Text {
                    text: model.name
                    x: 10
                    font: Qt.font({
                            pixelSize: 24,
                            unicodeCoverage: [Font.UnicodeBlock_BasicLatin]
                        })
                }
                Text {
                    text: model.country
                    x: 10
                    color: "gray"
                    font: Qt.font({
                            pixelSize: 12,
                            unicodeCoverage: [Font.UnicodeBlock_BasicLatin]
                        })
                }
                Rectangle {
                    color: "lightGreen"
                    x: 10
                    width: 460
                    height: 1
                }
            }
        }
    }

    ListView {
        anchors.fill: parent
        model: cityModel
        delegate: cityDelegate
        spacing: 5
    }
}

The example starts by instantiating the cityModel. As the model is not a singleton, it has to be instantiated from QML.

该示例首先实例化cityModel。由于模型不是单例模型,因此必须从QML实例化。

Then the delegate, cityDelegate is implemented as a Component. This means that it can be instantiated multiple times from QML. The model data is accessed via the model.name and model.country attached properties.

然后,委托CityLegate作为一个组件实现。这意味着它可以从QML中多次实例化。通过模型访问model.namemodel.country实现

Finally, the ListView element joins the model and the delegate, resulting in the list shown in the screenshots in this chapter.

最后,ListView元素将模型和委托连接起来,生成本章屏幕截图中显示的列表。

An interesting aspect of the QML is how the font of the Text elements is configured. The unicodeCoverage property lets us tell the Qt Quick Ultralite compiler what characters we would like to be able to render. When specifying fixed strings, the Qt Quick Ultralite tooling generates minimal fonts containing exactly the glyphs that we intend to use. However, since the model will provide us with dynamic data, we need to tell the font what characters we expect to use.

QML的一个有趣方面是如何配置文本元素的字体。Unicode Decorage属性允许我们告诉Qt Quick Ultralite编译器我们希望能够呈现哪些字符。在指定固定字符串时,Qt Quick Ultralite工具生成的最小字体正好包含我们想要使用的字形。然而,由于模型将为我们提供动态数据,我们需要告诉字体我们希望使用什么字符。

When rendering a complete font, sometimes you encounter the following style of warnings:

呈现完整字体时,有时会遇到以下类型的警告:

[2/7 8.8/sec] Generating CMakeFiles/cppmodel.dir/qul_font_engines.cpp, CMakeFiles/cppmodel.dir/qul_font_data.cpp
Warning: Glyph not found for character "\u0000"
Warning: Glyph not found for character "\u0001"
Warning: Glyph not found for character "\u0002"
Warning: Glyph not found for character "\u0003"
Warning: Glyph not found for character "\u0004"
Warning: Glyph not found for character "\u0005"
Warning: Glyph not found for character "\u0006"
Warning: Glyph not found for character "\u0007"
...

These can safely be disregarded, unless you expect to show the character in question.

如果你不想看到出这些输出,这些都可以放心地忽略不计。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值