前言
QAbstractTableModel 继承自 QAbstractItemModel,主要用于为 QTableView 提供相关接口,我们可以子类化该抽象类并实现相关接口。本文主要讲 QAbstractTableModel 为 QHeaderView 表头提供的接口如何使用。
(请确保自己已经熟悉了 rowCount、columnCount、data 等基础的接口)
表头相关接口的使用
一个完整的 QTableView 还包含了行列两个 QHeaderView 表头,表头的 model 可以独立设置,但是一般用 tablemodel 的相关接口提供数据就行了。接口如下:
//获取表头数据
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
//设置表头数据
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
我们可以看下 Qt 源码中这两个接口的默认实现:
QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_UNUSED(orientation);
if (role == Qt::DisplayRole)
return section + 1;
return QVariant();
}
bool QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role)
{
Q_UNUSED(section);
Q_UNUSED(orientation);
Q_UNUSED(value);
Q_UNUSED(role);
return false;
}
默认实现直接返回的行列号,我们可以进一步完善,还可以提供一个自定义接口直接设置表头的文本。效果如下:
void MyTableModel::setHorHeaderData(const QList<QString> &headers)
{
//自定义的表头设置接口,horHeaderData为QList<QString>成员变量
horHeaderData=headers;
emit headerDataChanged(Qt::Horizontal, 0, headers.count()-1);
}
QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//注意,如果用了sortproxymodel,这个section是实际数据的index,不是界面看到的index
//区分横表头和竖表头
if(orientation == Qt::Horizontal){
//这里我们只设置居中对齐和文本
if (role == Qt::DisplayRole){
//这里把横项列表头的文本设计为可以设置的
if(section>=0 && section<horHeaderData.count())
return horHeaderData.at(section);
return QString("Col %1").arg(section + 1);
}else if(role == Qt::TextAlignmentRole){
return Qt::AlignCenter;
}
}else{
if (role == Qt::DisplayRole)
return QString("Row %1").arg(section + 1);
else if(role == Qt::TextAlignmentRole)
return Qt::AlignCenter;
}
return QVariant();
}
bool MyTableModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
//设计为横项列表头可以设置
if (orientation == Qt::Horizontal && section>=0 && section<horHeaderData.count()) {
horHeaderData[section] = value.toString();
emit headerDataChanged(orientation, section, section);
return true;
}
return false;
}
表头相关操作
QHeaderView 提供了一些便捷设置,如是否选中后高亮、拖拽交换行等,可以使用 view 的 verticalHeader() 或 horizontalHeader() 接口获取实例对其进行设置。
table 设置 setSortingEnabled(true) 后就可以点击表头排序了,不过排序逻辑需要我们通过 model 的 sort 接口或者用 sortproxymodel 来完成。
table->setSortingEnabled(true);
其他常用设置项:
//表头实例
QHeaderView *header=table->horizontalHeader();
//拖拽交换行
header->setSectionsMovable(true);
//如何决策宽高
header->setSectionResizeMode(QHeaderView::Fixed);
//是否可以点击
header->setSectionsClickable(false);
//选中时高亮
header->setHighlightSections(false);
//默认宽高,放到table设置宽高的接口前,不然被覆盖
header->setDefaultSectionSize(100);
//最后一列填充
header->setStretchLastSection(true);
//排序
table->setSortingEnabled(true);
//设置第三列列宽
//table->setColumnWidth(2,200);
参考
官方文档:https://doc.qt.io/qt-5/qabstracttablemodel.html