好吧,我有一个非常基本的QStandardItemModel
,里面装满了一些数字。我设法在QTableView
显示它,没关系。我创建了一个新模型(QAbstractItemModel
或QAbstractProxyModel
的子类),它是某种现有模型的一个层 - 需要设置源模型,这个新层应该做一些转换真实的。
我的问题是,在顶层,说“层模型”,data( const QModelIndex & index, int role )
成员函数从未调用,但我想通过角色参数更改显示方法。
这是一个示例代码,它演示了原始模型的data(index,role)
始终被调用,而图层模型的data(index,role)
永远不会被调用。为什么? QTableView对象如何“跳过”顶层的data(index,role)
?
#include <QtGui/QApplication> #include <QtGui> #include <QStandardItemModel> class MyModel : public QStandardItemModel { public: MyModel(const int r, const int c, QObject* parent = 0) : QStandardItemModel(r,c,parent) {} QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const { qDebug() << "mymodel data"; return this->itemFromIndex(index)->data(role); } }; class MyProxyModel : public QAbstractProxyModel { public: MyProxyModel(QObject* parent = 0) : QAbstractProxyModel(parent) {} QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const { return this->sourceModel()->index(row,column,parent); } QModelIndex parent ( const QModelIndex & index ) const { return this->sourceModel()->parent(index); } QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const { return sourceIndex; } QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const { return proxyIndex; } QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const { qDebug() << "myproxymodel data"; return this->sourceModel()->data(index,role); } int rowCount ( const QModelIndex & parent = QModelIndex() ) const { return this->sourceModel()->rowCount(parent); } int columnCount ( const QModelIndex & parent = QModelIndex() ) const { return this->sourceModel()->columnCount(parent); } }; int main(int argc, char *argv[]) { QApplication app(argc,argv); MyModel model(8, 2); MyProxyModel mymodel; mymodel.setSourceModel(&model); QTableView tableView; tableView.setModel(&mymodel); tableView.horizontalHeader()->setStretchLastSection(true); for (int row = 0; row < 8; ++row) { for (int column = 0; column < 2; ++column) { QModelIndex index = model.index(row, column, QModelIndex()); model.setData(index, QVariant((row+1) * (column+1))); } } tableView.show(); return app.exec(); }
答案 0 :(得分:6)
因为QTableView使用模型索引来检索数据,可能是这样的。
QModelIndex index = model->index(row, column, parentIndex);
index.data(Qt::DisplayRole);
您将返回源模型的模型索引而不是代理模型的索引:
QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const {
return this->sourceModel()->index(row,column,parent);
}
尝试将模型索引转换为代理模型的索引
QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const {
return this->createIndex(row,column,row);
}
不要忘记重写地图以从源函数源和映射。
<强>解决方案强>
class MyTableProxyModel : public QAbstractProxyModel
{
Q_OBJECT
public:
MyTableProxyModel (QObject* parent = 0)
: QAbstractProxyModel(parent) {
}
QModelIndex index(int row, int column, const QModelIndex& parent=QModelIndex()) const {
return createIndex(row,column,row);
}
QModelIndex parent(const QModelIndex &index) const {
//Works only for non-tree models
return QModelIndex();
}
QModelIndex mapFromSource(const QModelIndex &source) const {
return index(source.row(), source.column(), source.parent());
}
QModelIndex mapToSource(const QModelIndex &proxy) const {
return (sourceModel()&&proxy.isValid())
? sourceModel()->index(proxy.row(), proxy.column(), proxy.parent())
: QModelIndex();
}
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
qDebug() << "myproxymodel data";
return mapToSource(index).data(role);
}
int rowCount ( const QModelIndex & parent = QModelIndex() ) const {
return sourceModel() ? sourceModel()->rowCount(parent) : 0;
}
int columnCount ( const QModelIndex & parent = QModelIndex() ) const {
return sourceModel() ? sourceModel()->columnCount(parent) : 0;
}
};