编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • Android提升进阶

  • iOS开发和进阶

  • Web开发和进阶

  • Linux应用开发

    • README
    • QML基础入门

      • README
      • Qml基础概念
      • Qml基础语法
      • Qml基础组件
      • Qml控件介绍
      • Qml高级功能
      • Canvas绘制
      • QML和C++
      • 多媒体应用
      • 模型和视图
        • 9.1 模型/视图架构
          • 9.1.1 模型/视图介绍
          • 9.1.2 模型(Model)
          • 9.1.3 视图(View)
          • 9.1.4 委托(Delegate)
        • 9.2 数据模型
          • 9.2.1 整数作为模型
          • 9.2.2 ListModel
          • 9.2.3 WorkerScript
          • 9.2.4 ObjectModel
          • 9.2.5 DelegateModel
          • 9.2.6 Package
          • 9.2.7 XmlListModel
          • 9.2.8 LocalStorage
          • 9.2.9 C++扩展QML模型
        • 9.3 视图类型
          • 9.3.1 ListView
          • 9.3.2 GridView
          • 9.3.3 视图过渡
          • 9.3.4 PathView
          • 9.3.5 TableView
        • 9.4 C++扩展QML模型
          • 9.4.1 C++扩展介绍
          • 9.4.2 核心步骤
          • 9.4.3 定义C++模型
          • 9.4.4 注册C++模型
          • 9.4.5 在QML中使用C++模型
          • 9.4.6 总结一下
      • 应用层开发
      • 图形和动画
    • QT核心库实践

    • Linux实践开发

  • Apps
  • Linux应用开发
  • QML基础入门
杨充
2025-09-17
目录

模型和视图

# 09.模型和视图

  • 9.1 模型/视图架构
    • 9.1.1 模型/视图介绍
    • 9.1.2 模型(Model)
    • 9.1.3 视图(View)
    • 9.1.4 委托(Delegate)
  • 9.2 数据模型
    • 9.2.1 整数作为模型
    • 9.2.2 ListModel
    • 9.2.3 WorkerScript
    • 9.2.4 ObjectModel
    • 9.2.5 DelegateModel
    • 9.2.6 Package
    • 9.2.7 XmlListModel
    • 9.2.8 LocalStorage
  • 9.3 视图类型
    • 9.3.1 ListView
    • 9.3.2 GridView
    • 9.3.3 视图过渡
    • 9.3.4 PathView
    • 9.3.5 TableView
  • 9.4 C++扩展QML模型
    • 9.4.1 C++扩展介绍
    • 9.4.2 核心步骤
    • 9.4.3 定义C++模型
    • 9.4.4 注册C++模型
    • 9.4.5 在QML中使用C++模型
    • 9.4.6 总结一下

# 9.1 模型/视图架构

# 9.1.1 模型/视图介绍

在 QML 中,模型/视图(Model/View)架构是一种用于管理和显示数据的强大模式。

它将数据(模型)与用户界面(视图)分离,使得数据的管理和显示更加灵活和高效。

# 9.1.2 模型(Model)

模型是数据的来源,负责存储和管理数据。

在 QML 中,模型可以是 ListModel、XmlListModel、JsonListModel 或自定义的 C++ 模型。

# 9.1.3 视图(View)

视图是数据的展示方式,负责将模型中的数据渲染到用户界面。

在 QML 中,视图可以是 ListView、GridView、TableView 等。

# 9.1.4 委托(Delegate)

委托定义了如何渲染模型中的每一项数据。

在 QML 中,委托通常是一个 Component,用于定义每一项的 UI 和行为。

# 9.2 数据模型

# 9.2.1 整数作为模型

  1. 简单易用:直接使用整数作为模型,无需定义复杂的数据结构。
  2. 动态生成:可以根据需要动态生成数字序列。
  3. 与视图组件结合:可以与 ListView、GridView、Repeater 等视图组件结合使用。
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    title: "Dynamic Integer Model"

    property int itemCount: 5 // 动态模型大小

    Column {
        anchors.centerIn: parent
        spacing: 10

        // 动态生成整数模型
        Repeater {
            model: itemCount // 使用属性动态设置模型大小
            delegate: Rectangle {
                width: 100
                height: 50
                color: "lightblue"
                border.color: "black"
                Text {
                    text: "Item " + (index + 1) // 使用索引
                    anchors.centerIn: parent
                }
            }
        }

        // 增加模型大小
        Button {
            text: "Add Item"
            onClicked: itemCount++
        }

        // 减少模型大小
        Button {
            text: "Remove Item"
            onClicked: if (itemCount > 0) itemCount--
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 9.2.2 ListModel

ListModel 是一个简单的列表模型,ListView 是一个用于显示列表数据的视图。案例:ListModel 和 ListView

// 定义模型
ListModel {
    id: fruitModel
    ListElement { name: "Apple"; color: "red" }
    ListElement { name: "Banana"; color: "yellow" }
    ListElement { name: "Grape"; color: "purple" }
}
1
2
3
4
5
6
7

# 9.2.3 WorkerScript

# 9.2.4 ObjectModel

ObjectModel 是一个用于存储 QML 对象的模型。

ObjectModel {
    id: objectModel
    Rectangle { width: 100; height: 100; color: "red" }
    Rectangle { width: 100; height: 100; color: "green" }
    Rectangle { width: 100; height: 100; color: "blue" }
}
1
2
3
4
5
6

# 9.2.5 DelegateModel

# 9.2.6 Package

# 9.2.7 XmlListModel

XmlListModel 是一个用于解析 XML 数据的模型。案例:XmlListModel 和 ListView

// 定义 XML 模型
XmlListModel {
    id: xmlModel
    source: "data.xml" // XML 文件路径
    query: "/items/item" // XPath 查询
    XmlRole { name: "name"; query: "name/string()" }
    XmlRole { name: "color"; query: "color/string()" }
}
1
2
3
4
5
6
7
8

# 9.2.8 LocalStorage

# 9.2.9 C++扩展QML模型

如果需要更复杂的数据管理,可以自定义 C++ 模型并集成到 QML 中。

  1. C++ 模型类:
#include <QAbstractListModel>
#include <QStringList>

class MyModel : public QAbstractListModel {
    Q_OBJECT
public:
    enum Roles {
        NameRole = Qt::UserRole + 1,
        ColorRole
    };

    MyModel(QObject *parent = nullptr) : QAbstractListModel(parent) {
        m_data << "Red" << "Green" << "Blue";
    }

    int rowCount(const QModelIndex &parent = QModelIndex()) const override {
        return m_data.size();
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
        if (!index.isValid() || index.row() >= m_data.size())
            return QVariant();

        switch (role) {
            case NameRole: return m_data.at(index.row());
            case ColorRole: return m_data.at(index.row()).toLower();
            default: return QVariant();
        }
    }

    QHash<int, QByteArray> roleNames() const override {
        QHash<int, QByteArray> roles;
        roles[NameRole] = "name";
        roles[ColorRole] = "color";
        return roles;
    }

private:
    QStringList m_data;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  1. 在 QML 中使用:
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    title: "Custom Model Example"

    ListView {
        anchors.fill: parent
        model: MyModel {} // 使用自定义模型
        delegate: Rectangle {
            width: ListView.view.width
            height: 50
            color: model.color // 使用模型数据
            Text {
                text: model.name // 使用模型数据
                anchors.centerIn: parent
                font.pixelSize: 20
                color: "white"
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 9.3 视图类型

# 9.3.1 ListView

# 9.3.2 GridView

GridView 是一个用于显示网格数据的视图。案例:GridView

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    title: "GridView Example"

    // 定义模型
    ListModel {
        id: colorModel
        ListElement { color: "red" }
        ListElement { color: "green" }
        ListElement { color: "blue" }
        ListElement { color: "yellow" }
        ListElement { color: "purple" }
        ListElement { color: "orange" }
    }

    // 定义视图
    GridView {
        anchors.fill: parent
        model: colorModel // 绑定模型
        delegate: colorDelegate // 绑定委托
        cellWidth: 100
        cellHeight: 100
    }

    // 定义委托
    Component {
        id: colorDelegate
        Rectangle {
            width: GridView.view.cellWidth
            height: GridView.view.cellHeight
            color: model.color // 使用模型数据
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 9.3.3 视图过渡

# 9.3.4 PathView

# 9.3.5 TableView

TableView 是一个用于显示表格数据的视图。案例:TableView

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    title: "TableView Example"

    // 定义模型
    ListModel {
        id: tableModel
        ListElement { name: "Alice"; age: 25; gender: "Female" }
        ListElement { name: "Bob"; age: 30; gender: "Male" }
        ListElement { name: "Charlie"; age: 35; gender: "Male" }
    }

    // 定义视图
    TableView {
        anchors.fill: parent
        model: tableModel // 绑定模型
        delegate: tableDelegate // 绑定委托
        columnWidthProvider: function(column) { return 200; } // 列宽
        rowHeightProvider: function(row) { return 50; } // 行高
    }

    // 定义委托
    Component {
        id: tableDelegate
        Rectangle {
            implicitWidth: 200
            implicitHeight: 50
            border.color: "black"
            Text {
                text: {
                    switch (column) {
                        case 0: return model.name;
                        case 1: return model.age;
                        case 2: return model.gender;
                        default: return "";
                    }
                }
                anchors.centerIn: parent
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 9.4 C++扩展QML模型

# 9.4.1 C++扩展介绍

在 QML 中,可以通过 C++ 扩展自定义模型(Model),以便在 QML 中使用复杂的数据结构和逻辑。

C++ 扩展的模型通常继承自 QAbstractItemModel 或其子类(如 QAbstractListModel 或 QAbstractTableModel),并通过 Q_PROPERTY 和 Q_INVOKABLE 暴露接口给 QML。

# 9.4.2 核心步骤

  1. 定义 C++ 模型类:
  • 继承 QAbstractListModel 或 QAbstractItemModel。
  • 实现 rowCount、data 和 roleNames 等虚函数。
  • 使用 Q_PROPERTY 和 Q_INVOKABLE 暴露属性和方法。
  1. 注册 C++ 模型到 QML: 使用 qmlRegisterType 将 C++ 模型注册为 QML 类型。

  2. 在 QML 中使用模型:实例化 C++ 模型,并与视图组件(如 ListView 或 GridView)绑定。

# 9.4.3 定义C++模型

1. 头文件(MyModel.h)

  • 定义模型类,继承自 QAbstractListModel 或 QAbstractItemModel。
  • 声明角色枚举、数据存储结构和虚函数(如 rowCount、data、roleNames)。
  • 使用 Q_PROPERTY 和 Q_INVOKABLE 暴露属性和方法。
#ifndef MYMODEL_H
#define MYMODEL_H

#include <QAbstractListModel>
#include <QStringList>

class MyModel : public QAbstractListModel {
    Q_OBJECT

public:
    // 角色枚举
    enum Roles {
        NameRole = Qt::UserRole + 1,
        ColorRole
    };

    // 构造函数
    explicit MyModel(QObject *parent = nullptr);

    // 虚函数重写
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

    // 自定义方法
    Q_INVOKABLE void addItem(const QString &item);
    Q_INVOKABLE void removeItem(int index);

private:
    // 数据存储结构
    QStringList m_data;
};

#endif // MYMODEL_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

2. 实现文件(MyModel.cpp)

  • 实现模型类的虚函数和自定义方法。初始化数据存储结构(如 QList 或 QStringList)。
#include "MyModel.h"

MyModel::MyModel(QObject *parent) : QAbstractListModel(parent) {
    // 初始化数据
    m_data << "Red" << "Green" << "Blue";
}

int MyModel::rowCount(const QModelIndex &parent) const {
    Q_UNUSED(parent);
    return m_data.size();
}

QVariant MyModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid() || index.row() >= m_data.size())
        return QVariant();

    switch (role) {
        case NameRole: return m_data.at(index.row());
        case ColorRole: return m_data.at(index.row()).toLower();
        default: return QVariant();
    }
}

QHash<int, QByteArray> MyModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[NameRole] = "name";
    roles[ColorRole] = "color";
    return roles;
}

void MyModel::addItem(const QString &item) {
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_data.append(item);
    endInsertRows();
}

void MyModel::removeItem(int index) {
    if (index < 0 || index >= m_data.size())
        return;

    beginRemoveRows(QModelIndex(), index, index);
    m_data.removeAt(index);
    endRemoveRows();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 9.4.4 注册C++模型

在 main.cpp 中注册模型:

#include "MyModel.h" // 包含模型头文件
int main(int argc, char *argv[]) {
    // 注册 C++ 模型到 QML
    qmlRegisterType<MyModel>("com.example.mymodel", 1, 0, "MyModel");
    return app.exec();
}
1
2
3
4
5
6

# 9.4.5 在QML中使用C++模型

import QtQuick
import QtQuick.Controls
import com.example.mymodel 1.0 // 导入 C++ 模型


Item {
    // 实例化 C++ 模型
    MyModel {
        id: myModel
    }
    Column {
        anchors.centerIn: parent
        spacing: 10
        // 显示模型数据
        ListView {
            width: 200
            height: 300
            model: myModel
            delegate: Rectangle {
                width: ListView.view.width
                height: 50
                color: model.color // 使用模型数据
                Text {
                    text: model.name // 使用模型数据
                    anchors.centerIn: parent
                    font.pixelSize: 20
                    color: "white"
                }
            }
        }
        // 添加数据
        Button {
            text: "Add Item"
            onClicked: myModel.addItem("New Color")
        }
        // 删除数据
        Button {
            text: "Remove Item"
            onClicked: myModel.removeItem(0) // 删除第一个项
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 9.4.6 总结一下

步骤 描述
定义 C++ 模型类 继承 QAbstractListModel 并实现虚函数
注册模型到 QML 使用 qmlRegisterType 注册模型
在 QML 中使用模型 实例化模型并与视图组件绑定

通过 C++ 扩展 QML 模型,可以实现复杂的数据管理和逻辑处理,同时保持 QML 的简洁性和灵活性。

上次更新: 2026/06/10, 11:13:41
多媒体应用
应用层开发

← 多媒体应用 应用层开发→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式