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还提供了基于项的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()函数与项数据有关,那里数据有几许种剧中人物,最中央的就是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;        else                            return QVariant();    }    if (orientation == Qt::Horizontal) {        if (role == Qt::DisplayRole)    return QVariant("column:" + QString::number;        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

完整代码见此处。

相关文章