QT编程(16): Qt Model

Qt Model介绍

Qt Model(模型)是Qt框架中模型/视图(Model/View)架构的核心组件,其设计源于经典的MVC(Model-View-Controller)模式,Qt将其优化为Model-View-Delegate(模型-视图-委托)结构,核心作用是实现数据与界面的解耦,负责数据的存储、检索、修改,并为视图(View)和委托(Delegate)提供标准化的数据访问接口,是Qt中处理复杂数据展示与交互的基础。

一、Qt Model的核心定位与架构关系

在Qt的模型/视图架构中,Model、View、Delegate三者分工明确、协同工作,其中Model承担"数据中枢"的角色,具体关系如下:

  • Model(模型):作为数据的"管理者",不负责数据的可视化,仅专注于数据本身的逻辑处理------包括与底层数据源(文件、数据库、内存数据等)的通信,提供数据的增删改查接口,以及在数据发生变化时通过信号通知视图更新。

  • View(视图):作为数据的"展示者",通过Model提供的接口获取数据,将其以列表、表格、树形等形式呈现给用户,不直接操作数据,仅负责界面渲染。

  • Delegate(委托):作为数据的"渲染与编辑者",负责定制数据项的显示样式(如颜色、字体)和编辑方式(如自定义输入控件),编辑时直接与Model通过索引交互,实现数据的个性化展示与编辑。

这种架构的核心优势的是解耦:同一Model可绑定多个View,实现同一数据的多形式展示;修改数据时,只需操作Model,所有关联的View会自动同步更新,大幅提升代码的可维护性和复用性。

二、Qt Model的核心基类

Qt中所有模型类均继承自抽象基类,其中QAbstractItemModel是所有模型的顶层基类,它定义了View和Delegate访问数据的统一接口,支持表格、列表、树形等多种数据结构,但其本身不能直接实例化,需通过子类实现具体功能。根据数据结构的不同,常用的基类子类分为以下两类:

1. 基础抽象子类(简化自定义模型开发)

  • QAbstractListModel:专为列表型数据设计,简化了单列数据模型的开发,提供了常用函数的默认实现,适合实现简单的单列列表数据(如下拉框选项)。

  • QAbstractTableModel:专为表格型数据设计,简化了多列多行数据模型的开发,无需手动处理行与列的索引关系,适合实现表格类数据展示(如数据报表)。

2. 关键概念:QModelIndex

由于Model支持层级化数据(如树形结构),Qt引入QModelIndex(模型索引)来定位数据项,每个数据项对应唯一的QModelIndex,通过行号、列号和父索引(用于树形结构的父子关系),View和Delegate可精准访问Model中的具体数据,这是Model处理复杂数据结构的核心机制之一。

三、Qt常用内置Model(开箱即用)

Qt提供了多种现成的模型类,无需自定义即可直接使用,覆盖大多数常见数据场景,具体如下:

1. QStringListModel

最简单的模型之一,专门用于存储和管理单列字符串列表,适合展示简单的字符串集合(如QListView的数据源、下拉框选项)。其局限性在于仅支持字符串类型,无法处理多列或复杂数据(如数字、图片),且数据变化时无法自动通知View,需手动重置模型。

示例场景:展示"苹果、香蕉、橙子"等水果名称的列表,可直接通过setStringList()方法填充数据,绑定到QListView即可显示。

2. QStandardItemModel

多用途通用模型,支持列表、表格、树形等多种数据结构,每个数据项(QStandardItem)可存储任意类型数据(文本、图标、颜色等),灵活性极高,是开发中最常用的内置模型之一。适合处理结构不固定、需要灵活扩展的数据场景,也可与QListView、QTableView、QTreeView任意绑定。

3. QFileSystemModel

专门用于访问本地文件系统的模型,可自动扫描指定目录下的文件和文件夹,提供文件名、文件大小、修改时间、文件类型等信息,无需手动处理文件操作逻辑。适合实现文件浏览器、文件选择器等界面,绑定到QTreeView或QTableView即可快速实现文件系统的可视化展示。

4. 数据库相关Model

用于实现数据库数据与界面的联动,需在项目文件(.pro)中添加QT += sql才能使用,常用类包括:

  • QSqlTableModel:直接关联数据库中的表,支持数据的增删改查,修改界面数据后可通过submitAll()提交到数据库,实现数据实时同步,适合展示和编辑数据库表数据(如学生信息表)。

  • QSqlQueryModel:用于执行自定义SQL查询语句,展示查询结果,默认只读,适合仅需展示数据库查询数据的场景。

  • QSqlRelationalTableModel:在QSqlTableModel的基础上,支持处理数据库表之间的关联关系(如外键),简化关联数据的展示与编辑。

5. QSortFilterProxyModel

代理模型,本身不存储数据,仅作为"中间层",对其他模型(如QStandardItemModel、QSqlTableModel)的数据进行过滤(如按关键词搜索)和排序(如按列升序/降序),不改变原模型的数据,适合需要对现有数据进行筛选和排序的场景(如数据搜索功能)。

四、Qt Model的核心特性

  • 数据与界面解耦:Model独立于View,同一Model可绑定多个View(如同一组数据同时用表格和树形图展示),修改Model数据后,所有关联View自动更新,降低代码耦合度。

  • 信号与槽机制 :Model内置信号(如dataChanged()rowsInserted()),当数据发生增删改时,自动发送信号通知View刷新;View的用户操作(如点击、编辑)也通过信号反馈给Model,实现双向联动。

  • 角色机制 :通过Qt::ItemDataRole区分数据的用途,同一数据项可提供多种表现形式(如Qt::DisplayRole用于显示文本、Qt::IconRole用于显示图标、Qt::ToolTipRole用于显示提示信息),Delegate可根据角色渲染不同样式。

  • 支持自定义扩展 :当内置模型无法满足需求时,可通过继承QAbstractItemModelQAbstractListModel等基类,重写核心方法(如data()setData()rowCount()),实现自定义数据逻辑(如复杂业务数据、自定义数据源)。

五、Qt Model的应用场景

Qt Model广泛应用于需要数据展示与交互的Qt应用中,典型场景包括:

  • 桌面应用的列表、表格、树形控件(如文件管理器、数据报表、配置列表);

  • 数据库应用的数据展示与编辑(如学生管理系统、库存管理系统);

  • 复杂层级数据的展示(如树形菜单、组织架构图);

  • QML与C++混合开发中,将C++数据模型暴露给QML视图,实现跨模块数据交互(如移动应用的列表展示)。

六、使用注意事项

  • 内置模型适合常规场景,复杂业务逻辑建议自定义模型,继承对应抽象基类并按需重写核心方法;

  • 使用数据库相关模型时,需确保正确配置数据库连接,并添加对应的模块依赖(QT += sql);

  • QStringListModel和QVariantListModel不支持数据变化的自动通知,修改数据后需手动重置模型;

  • 自定义模型时,需严格遵循Qt的接口规范,确保信号与槽的正确触发,否则会导致View无法同步更新数据;

  • 使用QSortFilterProxyModel时,需正确关联源模型,过滤和排序规则可通过重写对应方法自定义。

相关推荐
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript