qt模型/视图结构概述

Qt 的模型/视图结构(Model/View Architecture)是一种用于分离数据和其显示方式的设计模式,特别适合处理大量数据(如数据库表、文件系统、树形结构等)。它通过将数据的表示(模型)与数据的显示(视图)解耦,从而使得数据和 UI 表现彼此独立,允许更灵活和高效地管理和呈现数据。

模型/视图结构的核心组件

Qt 的模型/视图结构主要由以下三个部分组成:

  1. 模型(Model)
  2. 视图(View)
  3. 委托(Delegate)
1. 模型(Model)

模型负责存储和管理数据,并提供接口让视图和委托可以访问和修改数据。模型类的主要任务是将底层数据转换为视图所需的形式,并处理数据的变更。

Qt 提供了三种常用的模型基类:

  • QAbstractItemModel: 所有模型的基础类。
  • QStandardItemModel: 提供了一个基于 QStandardItem 的标准模型,适用于大部分场景。
  • QAbstractListModel: 适用于简单的线性数据(如列表)的模型。
  • QAbstractTableModel: 适用于二维表格数据的模型。
  • QAbstractTreeModel: 适用于树形结构数据的模型。

模型的职责:

  • 提供数据的读取接口(如 data())。
  • 提供数据的修改接口(如 setData())。
  • 提供数据结构信息(如行数和列数:rowCount()columnCount())。
  • 支持信号 dataChanged(),通知视图更新。
2. 视图(View)

视图负责显示模型中的数据。视图对象从模型中提取数据,并将其呈现在用户界面上。不同类型的视图可以使用相同的模型,展示数据的不同表现形式。

Qt 提供了以下几种标准视图类:

  • QListView: 适用于显示列表数据的视图。
  • QTableView: 适用于显示二维表格数据的视图。
  • QTreeView: 适用于显示树形结构数据的视图。
  • QColumnView: 适用于分栏式浏览的视图。

视图的职责:

  • 从模型中请求数据并在界面上呈现。
  • 响应用户的交互,如选择、编辑、排序等。
  • 将用户的操作(如编辑)反馈给模型。
3. 委托(Delegate)

委托负责渲染单元格内容,并处理编辑数据的输入。默认情况下,Qt 使用 QStyledItemDelegate 来绘制数据项和处理用户交互,但你可以自定义委托来控制项的外观和编辑行为。

委托的职责:

  • 绘制数据项的外观(如字体、颜色、格式等)。
  • 提供编辑控件,当用户需要修改数据时,委托可以提供编辑器。
  • 处理用户输入的验证、提交等逻辑。

你可以通过自定义委托来控制每个数据项的呈现和编辑行为,通常继承 QItemDelegateQStyledItemDelegate 实现自定义绘制和编辑逻辑。

模型/视图架构的工作流程

  • 模型 是数据的持有者。它不会直接与用户交互,而是通过信号-槽机制与视图保持同步。视图可以从模型中读取数据,也可以向模型写入数据。

  • 视图 显示来自模型的数据。视图会调用模型的 data() 方法来获得要显示的数据,并且会调用 setData() 方法将用户的修改传递给模型。

  • 委托 负责绘制视图中的每个数据项。如果用户需要编辑某个数据项,委托会创建一个输入控件来处理用户输入,之后将修改后的数据提交给模型。

核心功能示例

  1. QTableView 和 QStandardItemModel

    • QTableView 是一个二维表格的视图,而 QStandardItemModel 是一个方便使用的标准数据模型。
    import sys
    from PyQt5.QtWidgets import QApplication, QTableView, QStandardItemModel, QStandardItem
    
    app = QApplication(sys.argv)
    
    # 创建一个 QStandardItemModel
    model = QStandardItemModel(4, 2)  # 4 行 2 列
    model.setHorizontalHeaderLabels(['Name', 'Age'])
    
    # 填充数据
    model.setItem(0, 0, QStandardItem('Alice'))
    model.setItem(0, 1, QStandardItem('24'))
    model.setItem(1, 0, QStandardItem('Bob'))
    model.setItem(1, 1, QStandardItem('30'))
    
    # 创建一个 QTableView 并设置模型
    view = QTableView()
    view.setModel(model)
    view.show()
    
    sys.exit(app.exec_())
    
  2. 自定义模型
    可以通过继承 QAbstractTableModel 创建自定义模型。如下例展示了如何创建一个只读的表格模型。

    from PyQt5.QtCore import Qt, QAbstractTableModel
    
    class MyTableModel(QAbstractTableModel):
        def __init__(self, data):
            super().__init__()
            self._data = data
    
        def rowCount(self, index):
            return len(self._data)
    
        def columnCount(self, index):
            return len(self._data[0])
    
        def data(self, index, role):
            if role == Qt.DisplayRole:
                return self._data[index.row()][index.column()]
    
    data = [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
    ]
    
    model = MyTableModel(data)
    view = QTableView()
    view.setModel(model)
    view.show()
    

模型/视图结构的优点

  1. 解耦数据和显示逻辑:模型不关心数据如何显示,视图不关心数据的来源。
  2. 高扩展性:可以使用不同的视图来显示相同的数据,例如,可以同时使用 QTableViewQListView 来显示相同的模型。
  3. 易于维护:将数据和 UI 分离后,代码的维护和扩展变得更加方便。
  4. 大数据支持:使用懒加载的模型来处理大量数据时效率更高,因为数据只有在需要时才会加载。

总结

Qt 的模型/视图结构通过将数据管理(模型)与数据展示(视图)分离,提供了灵活、高效的数据处理方式。它特别适用于需要展示复杂数据结构的应用,如表格、树形结构或列表。在此基础上,委托可以进一步增强视图的表现力,使得模型/视图结构既灵活又强大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

先天无极编程圣体

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值