Qt接口框架生成器地址簿示例

这个示例展示了如何使用Qt接口框架生成器生成模型。

简介

本示例展示了如何使用Qt接口框架生成器,在qface文件中以model类型生成一个模型。

它将只解释如何使用model类型以及它的内部工作原理。对于Qt接口框架生成器的总体介绍,请参见Qt接口框架生成器气象示例

示例说明

示例中使用的接口定义语言(IDL)文件代表一个地址簿API。它包含一个单独的接口,提供作为模型的联系人,以及实际联系人的struct定义。

interface AddressBook {
    model<Contact> contacts;

    void insertContact(int index, Contact contact);
}

struct Contact {
    string forename;
    string name;
    int phone;
}

contact属性定义为由model<Contact>类型组成。前端模板将创建一个QIfPagingModel*类型的C++属性。一旦后端连接且属性初始化后,此属性的获取函数将返回一个有效的实例。这个QIfPagingModel实例可以从C++以及从QML使用,并且已经提供了使用所谓的分页概念以优化方式检索其数据的基功能。

对于后端接口,属性类型不同,将是一个QIfPagingModelInterface指针。这是必需的,因为QIfPagingModel也是QtInterfaceFramework的一个特性,并且与所有特性一样,它使用后端接口来实现前端和后端的分离。更多详细信息,请参阅概念和架构

后端插件需要为每个公开的属性实现QIfPagingModelInterface类。backend_simulator模板已经处理了这一点,并生成了所有需要的代码。

配置模拟后端插件

默认情况下,生成的模拟后端不会为模型填充任何数据,因为模板不知道应该提供什么内容。

对于此用例,可以使用default批注来配置模拟器以提供静态模拟数据。

这是在example-addressbook.yaml文件中完成的。

Example.If.AddressBookModule:
    config_simulator:
        simulationFile: "qrc:/plugin_resource/simulation.qml"

Example.If.AddressBookModule.AddressBook#contacts:
    config_simulator:
        default: [[ "John", "Doe", "12345" ], [ "Jane", "Doe", "67890" ]]

分配给default变量的JSON片段被Qt接口框架生成器解析,并被用于生成一个模拟后端,该后端创建两个联系人实例,并将它们作为联系人模型的内容返回。

示例应用程序

示例应用程序不是自动生成的,而是为类似其他示例的应用程序而设计的标准 QQmlEngine 设置。

ListView {
    Layout.fillWidth: true
    Layout.fillHeight: true
    model: addressBook.contacts
    clip: true

    delegate: ItemDelegate {
        width: parent.width
        height: 100
        text: model.item.forename + " " + model.item.name
    }
}

模型通过 addressbook 对象的 contacts 属性获取,然后传递给 ListView。委派可以访问真实联系人,使用 ItemRole,这是通过 model.item 公开的 QIfPagingModel

扩展模拟行为

因为 backend_simulator 模板只能生成存根,它不知道应该为 qface 文件的 insertContact 函数实现哪些行为。ifcodegen 将简单地生成一个打印出该函数未实现的提示消息的存根实现。

使用 simulationFile 注解可以解决这个限制,告诉自动生成器我们想提供自己的模拟 QML 文件。

在示例中,simulationFile 注解指向资源文件中的一个 QML 文件。资源文件可以像这样添加到构建系统中。

CMake:

set(plugin_resource_resource_files
    "simulation.qml"
)

qt_add_resources(addressbook_backend_simulator "plugin_resource"
    PREFIX
        "/plugin_resource"
    FILES
        ${plugin_resource_resource_files}
)

qmake:

RESOURCES += plugin_resource.qrc
在 QML 中提供模拟行为

自动生成的模拟后端代码使用 QIfSimulationEngine 从 QML 文件加载模拟行为。这个特殊的引擎确保自动生成的后端接口被提供给 QML 文件,并且可以从那里扩展。它还确保接口只对这个引擎实例可用,而对同一进程中运行的其他引擎不可用(例如在前端)。有关该引擎如何工作的更多信息,请参阅QIfSimulationEngine 文档。

使用 ifcodegen 进行模拟后端,模拟接口在 example.if.addressbook.simulation uri 中提供。提供的类型以模拟后端实现的后端接口命名。在我们的示例中,注册了两个类型

  • AddressBookBackend
  • ContactsModelBackend

我们的模拟 QML 文件如下所示

import QtQuick
import Example.If.AddressBookModule.simulation

Item {
    AddressBookBackend {
        id: backend
        property var settings : IfSimulator.findData(IfSimulator.simulationData, "AddressBook")

        function initialize() {
            print("AddressBookSimulation INITIALIZE")
            IfSimulator.initializeDefault(settings, backend)
            Base.initialize()
        }

        function insertContact(reply, index, contact) {
            print("BACKEND SIMULATION INSERT CONTACT")
            contacts.insert(index, contact);
            reply.setSuccess(true);
        }

        Component.onCompleted: {
            console.log("BACKEND SIMULATION CREATED")
        }
    }
}

它创建一个 AddressBookBackend 实例,并在 QML 代码加载后使用 Component.onCompleted 处理程序打印一条消息。

为了实现 insertContact 函数的行为,在 QML 中向 AddressBookBackend 对象添加了一个 JS 函数。这个函数接受三个参数,第一个参数是一个 PendingReply 对象,用于在请求成功或失败时通知前端。其他参数如 IDL 文件中定义。

要将提供的联系人插入我们的列表,我们使用 contacts 属性,它持有 contacts 属性的 QIfPagingModelInterface 实现的代码。这个实现提供了一些额外的便捷函数,可以供模拟轻松修改模型。在我们的例子中,我们只需调用 insert() 函数,让自动生成的实现继续进行。

示例项目 @ code.qt.io

© 2024 The Qt Company Ltd。此处包含的文档贡献是各自所有者的版权。此处提供的文档根据自由软件基金会在 GNU 自由文档许可证版本 1.3 项下的条款授权。Qt 和相关标志是 The Qt Company Ltd. 在芬兰和/或其他国家的注册商标。所有其他商标均为其各自所有者的财产。