• (转)Qt Model/View 学习笔记 (三)——Model类


    Model类

    基本概念

    在model/view构架中,model为view和delegates使用数据提供了标准接口。在Qt中,标准接口QAbstractItemModel类中被定义。不管数据在底层以何种数据结构存储,QAabstractItemModel的子类会以层次结构的形式来表示数据,结构中包含了数据项表。我们按这种约定来访问model中的数据项,但这个约定不会对如何显示这些数据有任何限制。数据发生改变时,model通过信号槽机制来通知关联的views。

    QTreeView - zhengjiu_520 - !snows snowy world!

    Model Indexes

    为了使数据存储与数据访问分开,引入了model index的概念。通过model index,可以引用model中的数据项,Views和delegates都使用indexes来访问数据项,然后再显示出来。因此,只有model需要了解如何获取数据,被model管理的数据类型可以非常广泛地被定义。Model indexes包含一个指向创建它们的model的指针,这会在配合多个model工作时避免混乱。

    QAbstractItemModel *model = index.model();

    model indexes提供了对一项数据信息的临时引用,通过它可以访问或是修改model中的数据。既然model有时会重新组织内部的数据结构,这时model indexes便会失效,因此不应该保存临时的model indexes。假如需要一个对数据信息的长期的引用,那么应该创建一个persistent model index。这个引用会保持更新。临时的model indexes由QModelIndex提供,而具有持久能力的model indexes则由QPersistentModelIndex提供。在获取对应一个数据项的model index时,需要考虑有关于model的三个属性:行数,列数,父项的model index。

    行与列

    在最基本的形式中,一个model可作为一个简单的表来访问,每个数据项由行,列数来定位。这必不意味着

    底层的数据用数组结构来存储。行和列的使用仅仅是一种约定,它允许组件之间相互通讯。可以通过指定

    model中的行列数来获取任一项数据,可以得到与数据项一一对应的那个index。

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

    Model为简单的,单级的数据结构如list与tables提供了接口,它们如上面代码所显示的那样,不再需要别的信息被提供。当我们在获取一个model index时,我们需要提供另外的信息。

    QTreeView - zhengjiu_520 - !snows snowy world!

    上图代表一个基本的table model,它的每一项用一对行列数来定位。通过行列数,可以获取代表一个数据项的model index .

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

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

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

    一个model的顶级项,由QModelIndex()取得,它们上式被用作父项。

    父项

    类似于表的接口在搭配使用table或list view时理想的,这种行列系统与view显示的方式是确切匹配的。

    然则,像tree views这种结构需要model提供更为灵活的接口来访问数据项。每个数据项可能是别的项的

    父项,上级的项可以获取下级项的列表。

    当获取model中数据项的index时,我们必须指定关于数据项的父项的信息。在model外部,引用一个数据

    项的唯一方法就是通过model index,因此需要在求取model index时指定父项的信息。

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

    QTreeView - zhengjiu_520 - !snows snowy world!

    上图中,A项和C项作为model中顶层的兄弟项:

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

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

    A有许多孩子,它的一个孩子B用以下代码获取:

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

    项角色

    model中的项可以作为各种角色来使用,这允许为不同的环境提供不同的数据。举例来说,Qt::DisplayRole被用于访问一个字符串,它作为文本会在view中显示。典型地,每个数据项都可以为许多不同的角色提供数据,标准的角色在Qt::ItemDataRole中定义。我们可以通过指定model index与角色来获取我们需要的数据:

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

    QTreeView - zhengjiu_520 - !snows snowy world!

    角色指出了从model中引用哪种类型的数据。views可以用不同的形式显示角色,因此为每个角色提供正确

    的信息是非常重要的。通过为每个角色提供适当数据,model也为views和delegates提供了暗示,如何正确地

    把这些数据项显给用户。不同的views可以自由地解析或忽略这些数据信息,对于特殊的场合,也可以定义

    一些附加的角色。

    概念总结:

    1,Model indexes为views与delegages提供model中数据项定位的信息,它与底层的数据结构无关。

    2,通过指定行,列数,父项的model index来引用数据项。

    3,依照别的组件的要求,model indexes被model构建。

    4,使用index()时,如果指定了有效的父项的model index,那么返回得到的model index对应于父项的某个孩子。

    5,使用index()时,如果指定了无效的父项的model index,那么返回得到的model index对应于顶层项的某个孩子。

    6, 角色对一个数据项包含的不同类型的数据给出了区分。

    使用Model Indexes

    QDirModel *model = new QDirModel;

         QModelIndex parentIndex = model->index(QDir::currentPath());

         int numRows = model->rowCount(parentIndex);

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

     {

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

             tring text = model->data(index, Qt::DisplayRole).toString();

             // Display the text in a widget.

         }

    以上的例子说明了从model中获取数据的基本原则:

    1,model的尺寸可以从rowCount()与columnCount()中得出。这些函数通常都需要一个表示父项的model index。

    2,model indexes用来从model中访问数据项,数据项用行,列,父项model index定位。

    3, 为了访问model顶层项,可以使用QModelIndex()指定。

    4, 数据项为不同的角色提供不同的数据。为了获取数据,除了model index之外,还要指定角色。

  • 相关阅读:
    第04组 Beta冲刺 (2/5)
    第04组 Beta冲刺 (1/6)
    第04组 Alpha冲刺 总结
    二叉树的递归与非递归
    各类典例模板
    选择题合辑2
    运算符重载
    链表题目
    集合的模拟实现(类模板)
    2018Final静态成员(黑名单)
  • 原文地址:https://www.cnblogs.com/takeaction/p/3662131.html
Copyright © 2020-2023  润新知