Qt提供了扳平拟Model/View框架供开发者使用。Qt提供了同效仿Model/View框架供开发者使用。

Qt提供了一套Model/View框架供开发者使用,Qt提供了一套Model/View框架供开发者使用

妇孺皆知,Qt提供了一致法Model/View框架供开发者使用,Model用来提供数据,
View则就此来供视觉层的来得。实际上就是同等拟遵循MVC设计模式的GUI框架,因为Qt还提供了默认的Delegate作为Controller来作为控制器。

阳,Qt提供了一样学Model/View框架供开发者使用,Model用来提供数据,
View则据此来提供视觉层的显得。实际上这是一样模仿遵循MVC设计模式的GUI框架,因为Qt还提供了默认的Delegate作为Controller来作为控制器。

图片 1

图片 2

MVC的益处这里就是不多说了,为了开发者使用方便,Qt还提供了根据项(Item)的Model/View实现—-QXxxWidget(QTableWidget、QListWidget等),对于有简的采用场景,这已够用了又用起来十分便宜。这里我们简要介绍下怎样利用由定义的数据模型,来满足各种花式的渴求。

MVC的利这里虽不多说了,为了开发者使用方便,Qt还提供了基于项(Item)的Model/View实现—-QXxxWidget(QTableWidget、QListWidget等),对于一些简约的行使场景,这曾经足足了并且应用起来很便宜。这里我们大概介绍下如何使用由定义之数据模型,来满足各种花式的求。

1. 摘适当的Model继承

1. 增选适宜的Model继承

1.1 标准数量模型

Qt兑现了4看似标准数量模型供我们以不同的情景下使用:

  1. QStringListModel:存储字符串列表
  2. QStandardItemModel:存储树状结构的擅自数据
  3. QFileSystemModel:存储当地文件系统上的文件和目录信息
  4. QSqlQueryModel、QSqlRelationalTableModel、QSqlTableModel:存储论及项目数据库被的多寡

如果使用情况及上述情况之一比较一般,则好设想继续对应之范类,并再次实现少数虚函数。

1.1 标准数据模型

Qt落实了4像样标准数量模型供我们于不同之场景下用:

  1. QStringListModel:存储字符串列表
  2. QStandardItemModel:存储树状结构的随意数据
  3. QFileSystemModel:存储地面文件系统上之文书与目录信息
  4. QSqlQueryModel、QSqlRelationalTableModel、QSqlTableModel:存储涉嫌项目数据库中之数量

设采取状态和上述情况之一比较相似,则可考虑继续对应的模型类,并再实现少数虚函数。

1.2 抽象数据模型

泛数据模型有3类:

  1. QAbstractItemModel:项范,这是具备数据模型的基类。
  2. QAbstractListModel:列表模型,结合QListView使用最相宜。
  3. QAbstractTableModel:表模型,结合QTableView使用最合适。

  4. 后续抽象模型


Qt官方提供了圆满之文档来赞助开发者来自定义模型类。根据官网,子类化模型需要开发者实现之效力(即要还实现的虚函数)按功能来分好分成三类:

  • 项数据处理:这同时可以分成三类—-只是念访问可编辑调整大小
  • 导航与下标创建。
  • 拖拽和MIME类型处理。

咱俩惟有需要依照好的功能要求来兑现中的一部分虚函数。

1.2 抽象数据模型

泛数据模型有3类:

  1. QAbstractItemModel:项范,这是有数据模型的基类。
  2. QAbstractListModel:列表模型,结合QListView使用最确切。
  3. QAbstractTableModel:表模型,结合QTableView使用最方便。

  4. 承抽象模型


Qt官方提供了周全之文档来帮助开发者来自定义模型类。根据官网,子类化模型需要开发者实现之作用(即需要还实现之虚函数)按职能来划分可以分成三类:

  • 件数据处理:这又有何不可分为三类—-只读访问可编辑调动大小
  • 导航与下标创建。
  • 拖拽和MIME类型处理。

俺们特需要以自己之意义要求来实现中的有虚函数。

3. 落实一个自定义模型

此我们来兑现一个自定义模型,并于QTableView中以她,因此我们选取继续QAbstractTableModel,这样咱们得举行的变更最少。但以QTableModel并无代表我们的数据结构就是Table状的,例如下面的例证中我们从来不需中数据结构。

下面我们只要贯彻如此一个数据模型:

  • 中不存储数据结构
  • 发明中的诸一个单元获得的数码是整型,并且值也列下标的平方
  • 型中之数据为只读

3. 实现一个自定义模型

此我们来实现一个自定义模型,并于QTableView中应用其,因此我们选取继续QAbstractTableModel,这样咱们得开的变动最少。但利用QTableModel并无代表我们的数据结构就是Table状的,例如下面的例证中我们向不欲中间数据结构。

脚我们如果贯彻这样一个数据模型:

  • 里头未存储数据结构
  • 表中之每一个单元获得的数额是整型,并且价值吗列下标的平方
  • 范中之数量也只读

3.1 实现CustomeModel

欠型继承自QAbstractTableModel,作为只念模型,我们惟有待实现以下几只虚函数:

virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual int rowCount(const QModelIndex &parent) const;
virtual int columnCount(const QModelIndex &parent) const;

data()函数和项数据有关,这里数据发生某些种角色(role),最基本的即使是Qt::DisplayRole,这里为了兑现在中成效,我们还处理了Qt::TextAlignmentRole角色:

QVariant MyTableModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole) {
        return index.column() * index.column();
    }
    if (role == Qt::TextAlignmentRole) {
        return Qt::AlignCenter;
    }
    return QVariant();
}

headerData()函数提供表头数据,包括个别单趋势(垂直、水平)的表头。同样,这里的数目也闹几许种植角色,我们特处理Qt::DisplayRole

QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical) {
        if (role == Qt::DisplayRole)    return QVariant("row:" + QString::number(section));
        else                            return QVariant();
    }
    if (orientation == Qt::Horizontal) {
        if (role == Qt::DisplayRole)    return QVariant("column:" + QString::number(section));
        else                            return QVariant();
    }
}

rowCount()columnCount()回来数据模父下标(QModelIndex)的行和列数量,这里我们若辨识下标是否行得通:因为方方面面表模型的父下标为无效下标,我们返回表模型的班数量;当下标有效时,我们回来的凡爸爸下标指向处的子表的序列

//  if `parent` is invalid, return the whole table row count!
//  else return the children row count of the `parent`
int MyTableModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    else
        return 10;
}

3.1 实现CustomeModel

该模型继承自QAbstractTableModel,作为单纯念模型,我们唯有需要贯彻以下几个虚函数:

virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual int rowCount(const QModelIndex &parent) const;
virtual int columnCount(const QModelIndex &parent) const;

data()函数和项数据有关,这里数据来几许栽角色(role),最中心的即使是Qt::DisplayRole,这里为贯彻在中作用,我们尚处理了Qt::TextAlignmentRole角色:

QVariant MyTableModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole) {
        return index.column() * index.column();
    }
    if (role == Qt::TextAlignmentRole) {
        return Qt::AlignCenter;
    }
    return QVariant();
}

headerData()函数提供表头数据,包括个别独方向(垂直、水平)的表头。同样,这里的数吧发出几许种角色,我们一味处理Qt::DisplayRole

QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical) {
        if (role == Qt::DisplayRole)    return QVariant("row:" + QString::number(section));
        else                            return QVariant();
    }
    if (orientation == Qt::Horizontal) {
        if (role == Qt::DisplayRole)    return QVariant("column:" + QString::number(section));
        else                            return QVariant();
    }
}

rowCount()columnCount()回数据模父下标(QModelIndex)的行和列数量,这里我们要甄别下标是否管用:因为全总表模型的父下标为无效下标,我们返回表模型的排数量;当下标有效时,我们返回的凡老子下标指向处的子表的队列

//  if `parent` is invalid, return the whole table row count!
//  else return the children row count of the `parent`
int MyTableModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    else
        return 10;
}

3.2 运行结果

图片 3

一体化代码见此处。

3.2 运行结果

图片 4

完全代码见此处。