添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 Qt基础

Qt的MVD模型和卡顿解决方案

Qt Widget没有把显示、控制、模型分离,我们通常说Qt采用了MVD模型,指的是 QAbstractItemView 这个模块采用了MVD模型,MVD模型主要涉及到以下三个类:

QAbstractItemDelegate;
QAbstractItemView;
QAbstractItemModel;

1.MVD

view 用于数据展示和部分控制, model 用于提供数据, delegate 负责与用户交互,以及绘制 view 单元格。和MVC设计模式相比,可以看出Qt中的MVD设计模式和MVC有很大差别的,MVD没有完全把显示和控制分离。三者通过下列函数关联起来:

//关联View和Delegate
void QAbstractItemView::setItemDelegate(QAbstractItemDelegate*);
void QAbstractItemView::setItemDelegateForColumn(int, QAbstractItemDelegate*);
void QAbstractItemView::setItemDelegateForRow(int, QAbstractItemDelegate*);
//关联View和Model
virtual void QAbstractItemView::setModel(QAbstractItemModel*);

2.视图

QAbstractItemView 是所有视图类的基类,我们若要定制视图,需要继承这个类。 QListView , QTableView , 和 QTreeView QAbstractItemView 的子类,依次代表列表、表格和树状表结构,似乎在99%的情况下,这三种视图就能够满足我们的需求了,并不需要我们通过继承 QAbstractItemView 定制新的视图。

3.模型

QAbstractItemModel 是所有模型类的基类,我们若要定制模型,需要继承这个类。在继承 QAbstractItemModel 时,至少必须实现:

// 为父节点下子节点分配索引
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
// 指定子节点的父节点
virtual QModelIndex parent(const QModelIndex &child) const override;
// 指定parent下子节点的行数
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
// 指定parent下子节点列数
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
// 指定索引下的数据
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

这些函数用于所有只读模型,并构成可编辑模型的基础。要在模型中启用编辑,还必须实现:

//编辑对应索引下表项的内容
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
//设置表项属性
virtual Qt::ItemFlags flags(const QModelIndex &index) const;

控制模型标题的显示方式,可以实现:

//设置表头内容