2024年6月14日发(作者:)
自定义model
Qt的model-view架构中的几个关键的概念。一个model中的每个数据元素都有
一个model索引。这个索引指明这个数据位于model的位 置,比如行、列等。
这就是前面我们曾经说到过的QModelIndex。每个数据元素还要有一组属性值,
称为角色(roles)。这个属性值并不是数据的 内容,而是它的属性,比如说,这
个数据是用来展示数据的,还是用于显示列头的?因此,这组属性值实际上是
Qt的一个enum定义的,比较常见的有 Qt::DisplayRole和Qt::EditRole,另
外还有Qt::ToolTipRole, Qt::StatusTipRole, 和Qt::WhatsThisRole等。并
且,还有一些属性是用来描述基本的展现属性的,比如Qt::FontRole,
Qt::TextAlignmentRole, Qt::TextColorRole, Qt::BackgroundColorRole等
list model
定位其中的一个数据只需要有一个行号通过QModelIndex::row()函数进行访
问;对于table model而言,这种定位需要有两个值:行号和列号,这两个值可
以通过QModelIndex::row()和 QModelIndex::column()这两个函数访问到。另
外,对于tree model而言,用于定位的可以是这个元素的父节点。
不仅仅是tree model,并且list model和table model的元素也都有自己的父
节点,只不过对于list model和table model,它们元素的父节点都是相同的,
并且指向一个非法的QModelIndex
所有的model,这个父节点都可以通过QModelIndex::parent()函数访问到。这
就是说,每个model的项都有自己的角色数据(属性),0个、1个或多个子节点。
既然每个元素都有自己的子元素,那么它们就可以通过递归的算法进行遍历,就
像数据结构中树的遍历一样,关于父节点的描述;
下面我们通过一个简单的例子来看看如何实现自定义model。
首先描述一下需求。这里我们要实现的是一个类似于货币汇率表的table
这是一个很简单的实现,直接用QTableWidget不就可以了吗?的确,如果直接
使用QTableWidget确实很方便。但是,试想一个包含了 100种货币的汇率表。
显然,这是一个二维表,并且,对于每一种货币,都需要给出相对于其他100
种货币的汇率(在这里,我们把自己对自己的汇率也包含在 内,只不过这个汇率
永远是1.0000)。那么,这张表要有100 x 100 = 10000个数据项。现在要求我
们减少存储空间。于是我们想,如果我们的数据不是显示的数据,而是这种货币
相对于美元的汇率,那么,其他货币的汇率都可以 根据这个汇率计算出来了。
比如说,我存储的是人民币相对美元的汇率,日元相对美元的汇率,那么人民币
相对日元的汇率只要作一下比就可以得到了。我没有必要 存储10000个数据项,
只要存储100个就够了。于是,我们要自己实现一个model(就是更优化的
model)。
CurrencyModel就是这样一个model。它
底层的数据
使用一个QMap double>类型的数据,作为key的QString是货币名字,作为value的double 是这种货币对美元的汇率。然后我们来看代码: class CurrencyModel : public QAbstractTableModel { public: CurrencyModel(QObject *parent = 0); void setCurrencyMap(const QMap int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; private: QString currencyAt(int offset) const; QMap }; CurrencyModel::CurrencyModel(QObject *parent) : QAbstractTableModel(parent) { } int CurrencyModel::rowCount(const QModelIndex & parent) const { return (); } int CurrencyModel::columnCount(const QModelIndex & parent) const { return (); } QVariant CurrencyModel::data(const QModelIndex &index, int role) const { if (!d())
发布评论