首页 > 其他分享 >(三)模型类

(三)模型类

时间:2023-10-28 12:02:18浏览次数:27  
标签:index 模型 视图 索引 model QModelIndex

1.基本概念

在模型/视图架构中,模型提供了一个标准接口,用于视图和委托访问数据。在Qt中,标准接口由QAbstractItemModel类定义。无论数据项如何存储在任何底层数据结构中,QAbstractItemModel的所有子类都将数据表示为包含项目表的层次结构。视图使用这种约定来访问模型中的数据项,但它们向用户呈现这些信息的方式没有限制。

(三)模型类_Qt

模型还通过信号和槽机制通知任何附加的视图有关数据的更改。

本节描述一些基本概念,这些概念对于其他组件通过模型类访问数据项的方式至关重要。后面几节将讨论更高级的概念。

模型索引

为了确保数据的表示和访问方式是分开的,引入了模型索引的概念。通过模型获得的每条信息都由模型索引表示。视图和委托使用这些索引来请求要显示的数据项。

因此,只有模型需要知道如何获取数据,模型管理的数据类型可以定义得相当通用。模型索引包含一个指向创建它们的模型的指针,这可以防止在使用多个模型时产生混淆。

QAbstractItemModel *model = index.model();

模型索引提供对信息片段的临时引用,可用于通过模型检索或修改数据。由于模型可能会不时地重新组织其内部结构,因此模型索引可能会变得无效,不应该被存储。如果需要对一个信息片段的长期引用,则必须创建一个持久的模型索引。这提供了对模型保持更新的信息的引用。临时模型索引由QModelIndex类提供,持久模型索引由QPersistentModelIndex类提供

要获得对应于数据项的模型索引,必须为模型指定三个属性:行号、列号和父项的模型索引。下面将详细描述和解释这些属性。

QModelIndex index = model->index(row, column, ...);

为列表和表等简单的单层数据结构提供接口的模型不需要提供任何其他信息,但是,如上代码所示,在获取模型索引时,我们需要提供更多的信息。

(三)模型类_Qt_02

行和列

该图展示了一个基本表模型的表示,其中每个项目由一对行号和列号定位。我们通过向模型传递相关的行号和列号来获得一个模型索引,该索引指向一个数据项。

QModelIndex indexA = model->index(0, 0, QModelIndex());

QModelIndex indexB = model->index(1, 1, QModelIndex());

QModelIndex indexC = model->index(2, 1, QModelIndex());

通过将QModelIndex()指定为父元素,总是可以引用模型中的顶层元素。

项目的父元素

当在表或列表视图中使用数据时,模型提供的类表接口是理想的。行和列的编号系统精确地映射到视图显示项目的方式。然而,像树视图这样的结构要求模型向其中的项公开更灵活的接口。因此,每个元素项也可以是另一个元素表的父元素,就像树视图中的顶层元素项可以包含另一个元素表一样。

在为模型元素请求索引时,必须提供元素父元素的一些信息。在模型外部,只有通过模型索引才能引用元素,因此还必须提供一个父模型索引:

QModelIndex index = model->index(row, column, parent);

(三)模型类_Qt_03

父元素、行和列

该图显示了一个树模型的表示,其中每个项都由一个父项、一个行号和一个列号引用。

元素"A"和"C"在模型中被表示为顶层的兄弟元素:

QModelIndex indexA = model->index(0, 0, QModelIndex());

QModelIndex indexC = model->index(2, 1, QModelIndex());

项目“A”有多个子项。下面的代码可以得到物品“B”的模型索引:

QModelIndex indexB = model->index(1, 0, indexA);

项目角色

模型中的项可以为其他组件执行各种角色,允许为不同的情况提供不同类型的数据。例如,Qt::DisplayRole用于访问一个可以在视图中显示为文本的字符串。通常,项包含许多不同角色的数据,标准角色由Qt::ItemDataRole定义。

我们可以向模型请求数据,方法是传入数据项对应的模型索引,并指定一个角色来获取我们想要的数据类型:

QVariant value = model->data(index, role);

(三)模型类_Qt_04

项目角色

角色指示模型引用的数据类型。视图可以以不同的方式显示角色,因此为每个角色提供适当的信息很重要。

创建新模型部分更详细地介绍了角色的一些特定用途。

项数据的最常见用途由Qt::ItemDataRole中定义的标准角色所涵盖。通过为每个角色提供适当的物品数据,模型可以向视图提供提示,并委托视图将物品如何呈现给用户。不同类型的视图可以根据需要自由地解释或忽略此信息。还可以为特定于应用程序的目的定义额外的角色。

总结

模型索引以一种独立于任何底层数据结构的方式向视图和委托提供关于模型所提供的项目位置的信息。

元素项通过行号和列号以及父元素项的model索引进行引用。

模型索引是由模型根据其他组件(如视图和委托)的请求构建的。

如果在使用index()方法请求索引时为父元素指定了有效的模型索引,则返回的索引指向模型中父元素下面的元素。获得的索引指向该项的一个子项。

如果在使用index()方法请求索引时,为父元素指定了无效的模型索引,则返回的索引指向模型中的顶层元素。

角色区分与项相关联的不同类型的数据。

2.使用模型索引

为了演示如何使用模型索引从模型中检索数据,我们设置了一个没有视图的QFileSystemModel,并在一个小部件中显示文件和目录的名称。虽然这不是使用模型的正常方式,但它展示了模型在处理模型索引时使用的约定。

QFileSystemModel的加载是异步的,以最小化系统资源使用。在处理这个模型时,我们必须考虑到这一点。

我们用以下方式构建文件系统模型:

// 创建一个新的QFileSystemModel实例,该实例会用于追踪和展示文件系统的状态。
QFileSystemModel *model = new QFileSystemModel;

// 连接模型的directoryLoaded信号到一个lambda函数。每当一个目录被加载完成时,这个lambda函数就会被调用。
connect(model, &QFileSystemModel::directoryLoaded, [model](const QString &directory) {

    // 获取目录在模型中的索引
    QModelIndex parentIndex = model->index(directory);

    // 获取该目录下的所有文件和子目录的数量
    int numRows = model->rowCount(parentIndex);

});

// 设置模型的根路径。QDir::currentPath会返回当前运行的程序的工作目录。模型会追踪这个路径下所有文件和子目录的变化。
model->setRootPath(QDir::currentPath);

在这种情况下,我们首先设置一个默认的QFileSystemModel。我们将它连接到一个lambda,使用该模型提供的index()的特定实现来获取父索引。在lambda表达式中,我们使用rowCount()函数计算模型的行数。最后,我们设置QFileSystemModel的根路径,让它开始加载数据并触发lambda表达式。

为简单起见,我们只对模型第一列中的项感兴趣。我们依次检查每一行,获取每行中第一个项目的模型索引,并读取存储在模型中该项目的数据。

for (int row = 0; row < numRows; ++row) {

        QModelIndex index = model->index(row, 0, parentIndex);

为了获得模型索引,我们指定行号、列号(第一列为0),以及我们想要的所有元素的父元素对应的模型索引。存储在每一项中的文本可以通过模型的data()函数取得。我们指定模型索引和DisplayRole以字符串形式获取项目的数据。

QString text = model->data(index, Qt::DisplayRole).toString();
// Display the text in a widget.
}

上面的例子演示了从模型中检索数据的基本原则:

使用rowCount()和columnCount()可以得到模型的维度。这些函数通常需要指定一个父模型索引。

模型索引用于访问模型中的项。指定项目需要行、列和父模型索引。

要访问模型中的顶层元素,可以用QModelIndex()指定一个空的模型索引作为父索引。

项目包含不同角色的数据。要获取特定角色的数据,必须向模型提供模型索引和角色。

3.拓展

通过实现QAbstractItemModel提供的标准接口,可以创建新的模型。在创建新模型一节中,我们通过创建一个方便的即用模型来保存字符串列表来演示这一点。


标签:index,模型,视图,索引,model,QModelIndex
From: https://blog.51cto.com/u_16324960/8068823

相关文章

  • AI大模型技术与应用路线图
    跟进AI科技的发展,思考最新AI技术在应用中的场景、机会和范式;跟大家分享下AI大模型与应用路线图。 整个思考导图分两个部分:围绕GPT等通用大语言模型,讲解典型应用场景,应用范式,开发范式这几个层面的思考逻辑; 围绕多模态AI模型,列举一些典型的多模态路径,多模态学习中目前......
  • 深度学习(统计模型参数量)
    统计模型参数量,方便判断不同模型大小:importtorchimporttorch.nnasnn#自定义AlexNet模型classAlexNet(nn.Module):def__init__(self):super(AlexNet,self).__init__()self.conv1=nn.Conv2d(1,96,kernel_size=11,stride=4)self.......
  • OSG开发笔记(二十九):OSG加载模型文件、加载3DMax三维型文件Demo
    前言  Osg深入之后需要打开模型文件,这些模型文件是已有的模型文件,加载入osg之后可以在常见中展示模型文件,该节点可以操作,多个逼真的模型的节点就实现了基本的场景构建。<br>Demo  <br>说明  三维模型文件一般是由专业的三维建模人员完成,可以去buy通用模型,但是定制模型......
  • blender模型展uv3.6
    有时候uv贴图直接按U展开效果不理想,不同的模型适合的展开方式也会有一定的差异。以下是几种模型的展开方式,可做参考。在展uv前可以打开uv选区同步,以便更好控制所有网格位置。人物角色面部展开在后面选中中间的那根线一直到发际线标记缝合边。然后A全选U键选择“展开”......
  • 大语言模型Fine-tuning踩坑经验之谈
    前言 由于ChatGPT和GPT4兴起,如何让人人都用上这种大模型,是目前AI领域最活跃的事情。当下开源的LLM(Largelanguagemodel)非常多,可谓是百模大战。面对诸多开源本地模型,根据自己的需求,选择适合自己的基座模型和参数量很重要。选择完后需要对训练数据进行预处理,往往这一步就难......
  • 行行AI公开课:飞书无代码平台AI技术负责人邓范鑫——从第一性原理看大模型Agent技术
    当我们进入智能时代,开始思考:什么将会成为这个时代的核心载体?是App?是网站?还是Agent?也许几年后的现实才能给出答案,但历史告诉我们一个新鲜事物的演进总会找到一个稳定的术语来概括这个载体,而今天我们看到Agent最具有这个潜力。几个月前,OpenAI在内部就开始高度关注智能体(Agent)领......
  • Django和Vue.js是两种不同的框架,它们各自有自己的特点和用途¹。 **Django**¹: - Dja
    Django和Vue.js是两种不同的框架,它们各自有自己的特点和用途¹。**Django**¹:-Django是一个开放源代码的PythonWeb应用框架¹。-它采用了MTV(模型,视图,模板)的软件设计模式¹。-Django可以方便、快捷地创建高品质、易维护、数据库驱动的应用程序¹。-Django还包含许多功能......
  • 如何设置模型的粗糙质感?
    1、粗糙贴图的原理粗糙贴图(RoughnessMap)是一种用于模拟物体表面粗糙程度的贴图技术。它通过控制光线在物体表面的散射程度来实现不同粗糙度的效果。粗糙贴图通常使用灰度图像来表示不同部分的粗糙度,白色表示较光滑的表面,黑色表示较粗糙的表面。粗糙贴图的原理可以简单地描述为......
  • 抢先体验!星河社区ERNIE Bot SDK现已支持文心大模型4.0
    在2023百度世界大会上,百度创始人、董事长兼首席执行官李彦宏正式官宣发布文心大模型4.0!文心大模型4.0,相比3.5版本,理解、生成、逻辑、记忆四大能力都有显著提升。其中理解和生成能力的提升幅度相近,而逻辑和记忆能力的提升则更大,逻辑的提升幅度达到理解的近3倍,记忆的提升幅度也达到......
  • R语言具有Student-t分布改进的GARCH(1,1)模型的贝叶斯估计|附代码数据
    最近我们被客户要求撰写关于GARCH的研究报告,包括一些图形和统计输出。本说明介绍了具有Student-t改进的GARCH(1,1)模型的贝叶斯估计方法介绍摘要本说明介绍使用Student-t改进的GARCH(1,1)模型对汇率对数收益进行贝叶斯估计。自Engle(1982)的开创性论文以来,使用时间序列模型改变波动率的......