QAbstractItemModel有一个setHeaderData(int section,.....)方法,该方法根据标头方向采用一个是行还是列的节。我有一个包含几个表的模型,这些表都是顶层项的子项。也就是说,我的模型层次结构的第一层(在不可见的根目录下)由8行组成,每行都有一个作为表的子元素(当然总共有8个表)。似乎setHeaderData将为视图提供第一级的标题,但是如何为这些子表指定标题数据呢?QTableView有一个setRootIndex()方法,因此它可以深入到模型层次结构中并在这些子表中显示数据,我希望setHeaderData也具有根索引,但事实并非如此。我可以在QTableView上手动设置标题,但是
不幸的是,模型API并不提供执行此操作的好方法。最简单的解决方案是headerData
根据当前使用的根索引使模型返回的值不同。但是,这意味着模型需要知道视图的状态(更具体地说,是根索引),这不是您通常想要的。
我认为设置代理模型可以很好地解决此问题。这是如何实现的:
class ChildHeadersProxy : public QSortFilterProxyModel {
public:
static const int HorizontalHeaderRole = Qt::UserRole + 1;
static const int VerticalHeaderRole = Qt::UserRole + 2;
void setRootIndex(const QModelIndex& index) {
m_rootIndex = index;
if (sourceModel()) {
emit headerDataChanged(Qt::Horizontal, 0, sourceModel()->columnCount(m_rootIndex));
emit headerDataChanged(Qt::Vertical, 0, sourceModel()->rowCount(m_rootIndex));
}
}
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const {
if (sourceModel() && m_rootIndex.isValid()) {
int role = orientation == Qt::Horizontal ? HorizontalHeaderRole : VerticalHeaderRole;
QStringList headers = sourceModel()->data(m_rootIndex, role).toStringList();
if (section >= 0 && section < headers.count()) {
return headers[section];
}
}
return QSortFilterProxyModel::headerData(section, orientation, role);
}
private:
QModelIndex m_rootIndex;
};
此代理模型使用源模型通过两个自定义角色提供的标头。例如,如果使用QStandardItemModel
,则设置标头就是这样简单:
model.item(0, 1)->setData(QStringList() << "h1" << "h2",
ChildHeadersProxy::HorizontalHeaderRole);
model.item(0, 1)->setData(QStringList() << "vh1" << "vh2",
ChildHeadersProxy::VerticalHeaderRole);
哪里model.item(0, 1)
是对应的根项目。设置视图将如下所示:
QTableView view;
ChildHeadersProxy proxy;
proxy.setSourceModel(&model);
view.setModel(&proxy);
更改根索引看起来像:
view.setRootIndex(proxy.mapFromSource(model.index(0, 1)));
proxy.setRootIndex(model.index(0, 1));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句