我正在尝试创建一个代理模型,以动态映射源模型中的项目。
打算从那里执行QIdentityProxyModel
之后,我发现实际上不可能通过检查4个核心功能来复制它:
mapFromSource()
mapToSource()
index()
parent()
考虑基于
QIdentityProxyModel
:mapFromSource()
QModelIndex ProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
if(sourceIndex.isValid())
return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer());
else
return QModelIndex();
}
mapToSource()
QModelIndex ProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
if(proxyIndex.isValid())
return sourceModel()->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
else
return QModelIndex();
}
指数()
QModelIndex ProxyModel::index(int row, int column, const QModelIndex &parent) const
{
const QModelIndex sourceParent = mapToSource(parent);
const QModelIndex sourceIndex = sourceModel()->index(row, column, sourceParent);
return mapFromSource(sourceIndex);
}
parent()
QModelIndex ProxyModel::parent(const QModelIndex &index) const
{
const QModelIndex sourceIndex = mapToSource(index);
const QModelIndex sourceParent = sourceIndex.parent();
return mapFromSource(sourceParent);
}
发行
问题出在
mapToSource()
行return sourceModel()->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
QAbstractItemModel::createIndex
是 protected 函数,除非调用者被声明为好友,否则无法使用。如果不直接修改QAbstractItemModel
类,那显然不是一个选择。唯一的选择是使用常规QAbstractItemModel::index
,但这需要QModelIndex
形式的父级作为参数之一。但是这样做:return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), proxyIndex.parent());
由于
parent()
函数依赖mapToSource()
,而现在变成,则导致无限循环。for example here显示的另一种方法依赖于上述函数中查询的
QPersistentModelIndex
对象的存储映射。这种方法虽然可行,但有几个缺点:因此,我的问题是:
是否有另一种方法可以动态处理分层代理模型,而不依赖于createIndex()且不陷入函数调用的无限循环?
实际上是否有必要相对于源结构在存储中创建和维护代理模型的结构,还是有办法创建动态代理模型?
谢谢!
最佳答案
也许这是一个较晚的答复,但是我也遇到了同样的问题。我通过将sourceModel()转换为模型来解决它,同时我将ProxyModel
声明为 friend 。
这是我的mapToSource定义:
QModelIndex ProxyModel::mapToSource(const QModelIndex& proxyIndex) const
{
Model* pModel = qobject_cast<Model*>(sourceModel());
if (!pModel || !proxyIndex.isValid()) return QModelIndex();
...
return pModel->createIndex(row, col, proxyIndex.internalPointer());
}
和 friend 声明:
class Model : public QAbstractTableModel
{
Q_OBJECT
friend class ProxyModel;
...
};
我了解您对仅使用QAbstractItemModel接口(interface)的担心(相信我,我有相同的想法),但是让我们面对现实吧
ProxyModel
只能与我的Model
一起使用,而不能与其他任何方式一起使用(至少根据我的实现)。因此,在这样的“友谊”中我看不到任何不好的地方。至于UB,这里也不应该有任何问题,因为如果提供了除我以外的其他模型,则qobject_cast
将返回0
。关于c++ - QAbstractProxyModel子类中的sourceModel()-> createIndex(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23896182/