JSON 文件 在QML绑定Model与解读

在 QML 中,ListViewmodel 是两种非常常用的控件,它们常常用于显示一组数据。model 用于存储数据,而 ListView 用于显示这些数据。特别是当我们处理多层嵌套的 JSON 数据时,理解如何在 QML 中使用 ListViewmodel 是非常重要的。

1. JSON 数据格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它具有以下特点:

  • 易于阅读和编写。
  • 易于机器解析和生成。

JSON 主要由两种结构组成:

  1. 对象:一组由键值对组成的数据。
  2. 数组:一组有序的值。

例如,下面是一个描述课程和模块信息的 JSON 示例:

{
    
    
    "schoolName": "现代编程学院",
    "location": "上海",
    "courses": [
        {
    
    
            "courseId": 101,
            "courseName": "Python 编程基础",
            "instructor": "张三",
            "duration": 30,
            "modules": [
                {
    
    
                    "moduleId": 1,
                    "moduleName": "Python 基础语法",
                    "time": 10,
                    "content": "介绍 Python 的基础语法,变量、数据类型和控制流。"
                },
                {
    
    
                    "moduleId": 2,
                    "moduleName": "面向对象编程",
                    "time": 10,
                    "content": "讲解面向对象的基本概念和如何在 Python 中实现类与对象。"
                },
                {
    
    
                    "moduleId": 3,
                    "moduleName": "Python 高级特性",
                    "time": 10,
                    "content": "学习 Python 的高级特性,如装饰器、生成器等。"
                }
            ]
        },
        {
    
    
            "courseId": 102,
            "courseName": "前端开发",
            "instructor": "李四",
            "duration": 40,
            "modules": [
                {
    
    
                    "moduleId": 1,
                    "moduleName": "HTML 基础",
                    "time": 15,
                    "content": "介绍 HTML 的基础标签和网页结构。"
                },
                {
    
    
                    "moduleId": 2,
                    "moduleName": "CSS 样式",
                    "time": 15,
                    "content": "讲解 CSS 的选择器、样式属性以及布局技巧。"
                },
                {
    
    
                    "moduleId": 3,
                    "moduleName": "JavaScript 编程",
                    "time": 10,
                    "content": "学习 JavaScript 的基本语法、DOM 操作等。"
                }
            ]
        }
    ]
}

2. QML 中的 ListViewmodel

ListView 控件

ListView 是 QML 中用来显示一组数据的控件,它需要一个 model 来提供数据。ListView 会根据模型中的数据生成每个项,并通过 delegate 来指定如何显示这些项。

model 属性

model 是 QML 中存储数据的结构。常见的 model 类型有:

  • ListModel:简单的列表模型。
  • XmlListModel:XML 数据模型。
  • JSON 数据:可以通过 QVariantMapQVariantList 将 JSON 数据传递给 QML。

在我们的例子中,model 是从 C++ 中传递过来的 JSON 数据(通过 QVariantMap),然后 QML 会读取并展示。

delegate 属性

delegateListView 用来定义如何展示每一项数据的模板。在 delegate 中,我们使用 modelData 来访问每一项的属性。

3. 如何使用 ListViewmodel 展示 JSON 数据

我们将通过一个简单的例子,展示如何使用 ListViewmodel 来展示上述 JSON 数据。

3.1 显示学校信息和课程

我们有一个包含学校信息和课程列表的 JSON 数据。在 QML 中,我们将用 ListView 展示所有的课程,而每个课程下面的模块列表将使用嵌套的 ListView 来显示。

QML 代码:
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 600
    height: 600
    title: "课程列表"

    // 获取 C++ 传递过来的 QVariantMap
    property var school: schoolData

    // 显示学校信息
    Column {
        spacing: 20
        anchors.centerIn: parent

        Text {
            text: "学校名称: " + school.schoolName
            font.pointSize: 20
        }
        Text {
            text: "位置: " + school.location
            font.pointSize: 16
        }

        // 显示课程列表
        ListView {
            width: parent.width
            height: 300

            model: school.courses

            delegate: Item {
                width: parent.width
                height: 180

                Rectangle {
                    width: parent.width
                    height: 180
                    color: "lightblue"
                    border.color: "blue"
                    radius: 10

                    Column {
                        anchors.centerIn: parent
                        spacing: 10

                        Text {
                            text: "课程名称: " + modelData.courseName
                            font.pointSize: 18
                        }
                        Text {
                            text: "讲师: " + modelData.instructor
                            font.pointSize: 14
                        }
                        Text {
                            text: "课程时长: " + modelData.duration + " 小时"
                            font.pointSize: 14
                        }

                        // 显示课程模块列表
                        ListView {
                            width: parent.width
                            height: 100

                            model: modelData.modules

                            delegate: Item {
                                width: parent.width
                                height: 60

                                Rectangle {
                                    width: parent.width
                                    height: 60
                                    color: "lightgreen"
                                    border.color: "green"
                                    radius: 5

                                    Column {
                                        anchors.centerIn: parent
                                        spacing: 5

                                        Text {
                                            text: "模块名称: " + modelData.moduleName
                                            font.pointSize: 12
                                        }
                                        Text {
                                            text: "时长: " + modelData.time + " 小时"
                                            font.pointSize: 12
                                        }
                                        Text {
                                            text: "内容: " + modelData.content
                                            font.pointSize: 12
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

4. 解析 QML 代码

  1. 学校信息

    • Column 中,展示学校的名称和位置。我们使用 school.schoolNameschool.location 来显示这些信息。
  2. 课程列表

    • 使用 ListView 显示 school.courses 中的每个课程。每个课程的名称、讲师和课程时长通过 modelData 访问。
  3. 模块列表

    • 每个课程内有一个 ListView,显示该课程的所有模块。模块的名称、时长和内容通过 modelData 访问并显示。
  4. modelData

    • modelData 用来访问每一项的数据。在 ListViewdelegate 中,modelData 引用当前列表项的数据。

5. 总结

通过上面的例子,我们学会了如何:

  • 传递 JSON 数据到 QML:通过 C++ 将 JSON 数据传递给 QML。
  • 使用 ListView 展示嵌套数据:通过嵌套的 ListView 来展示 JSON 数据中的多层信息(如课程和模块)。
  • 使用 modelData 访问数据:通过 modelData 访问每一项的数据,确保展示正确的信息。

在 QML 中,ListViewmodel 提供了一种非常灵活和强大的方式来展示多层嵌套的 JSON 数据,只需确保每个层级的数据正确传递并在 delegate 中正确访问。