一、概述
最近在研究QTableView支持多级表头的事情,百度了下网上资料还是挺多的。实现的方式总的来说有2种,效果都还不错,最主要是搞懂其中的原理,做到以不变应万变。
实现多级表头的方式有以下两种方案
- 行表头和列表头都是用一个表格去模拟
- 重写QHeadView
以上两种方式都可以实现多级表头,各有利弊,并且已经有人投入项目使用。
我个人还是比较偏向于第二种方式,因为这样我们才可以更好的了解Qt的底层,了解Qt的绘图机制,并且这样实现的效率也是比较高的,而且合理一些,比较可控(个人理解)。
后来我在网上找到了一个哥们写的控件,项目名字叫做RbTableHeaderView,挺不错的,可以实现我们要的功能,但是效果还是差一些,如果需要更友好的交互效果,那么还需要在继续完善这个demo。
今天闲来无事,找到了一个开源的网站,上边好多Qt的库,虽然有一些是很早以前的东西,但是也很值得我们去学习。为什么会提到这个网站呢?因为这个网站上就有我们要的这个多级表头事例,和上边提到的那个哥们的事例不谋而合。
想要学习更多开源事例的可以到openDesktop上去看看。
下面我们就来讲解这个多节表头的实现方式,代码比较简单,主要是大家理解下这个实现方式,可以加以扩展。
二、效果展示
多级表头的效果下图所示,很糙粗的一个demo,大家将就着看吧。
三、定制表头
定制表头我们主要是要重写2个东西,分别是数据源QAbstractTableModel和表头QHeaderView
1、重写数据源
数据源就是为视图提供数据的model,我们的所有显示的内容数据都来自这个model。
对于外部程序填充数据时和往常使用同样的方式
for (int i = 0; i < 10; i++)
{
QList<QStandardItem*> items;
for (int j = 0; j < 8; j++)
{
items.append(new QStandardItem(QString("item(%1, %2)").arg(i).arg(j)));
}
dataModel->appendRow(items);
}
重写了这个数据源后,我们主要是为了完成data的返回数据过程,View最关心的就是这个接口
class RbTableHeaderModel : public QAbstractTableModel
{
Q_OBJECT
public:
// override
virtual QVariant data(const QModelIndex &index, int role) const;
private:
// properties
int row_count_prop;
int column_count_prop;
// inherent features
RbTableHeaderItem* root_item;
};
下面就是data的函数实现,是不是大失所望,所有的额操作好像被封装到RbTableHeaderItem这个节点中去了。
QVariant RbTableHeaderModel::d