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;
控制模型标题的显示方式,可以实现:
//设置表头内容