[英]Wrong QModelIndex on QTreeView using custom QSortFilterProxyModel
I have a QTreeView
based on a QStandardItemModel
filled with subclassed QStandardItem
. 我有一个基于
QStandardItemModel
的QTreeView
,其中填充了子类QStandardItem
。 The Item-sublcass just has two more datapointers and do not effect the item in any other way, so PTSModelItem
behaves like QStandardItem
. Item-sublcass仅具有两个数据指针,并且不会以任何其他方式影响该项目,因此
PTSModelItem
行为类似于QStandardItem
。
I am using a custom QSortFilterProxyModel
by subclassing filterAcceptsRow()
to enable filtering on the custom datapointers. 我通过子类
filterAcceptsRow()
来使用自定义QSortFilterProxyModel
来启用对自定义数据filterAcceptsRow()
过滤。
The treeView
is shown correct, until i enable the filter. 在未启用过滤器之前,
treeView
显示正确。 Then the List element is never filtered out and the child-elements are missing completly on the list (not child matches) or completly shown (at least one child matches). 这样,List元素就永远不会被滤除,并且子元素完全丢失在列表中(不是子匹配项)或完全显示出来(至少一个子匹配项)。
The problem i encounter, the generated index in filterAcceptsRow()
is always the List Element (Child of rootItem
) even with the source_row increasing. 我遇到的问题是,即使source_row增加,在
filterAcceptsRow()
生成的索引始终是列表元素( rootItem
子元素)。
Model with parameter values for filterAcceptsRow(int source_row, QModelIndex source_parent)
: 具有
filterAcceptsRow(int source_row, QModelIndex source_parent)
参数值的模型:
RootItem (invisible)
|-List1
| |-Child1
| |-Child2
| |-Child3
|-List2
| |-Child1
| |-Child4
The problem is, indepentend from source row, calling 问题是,与源行无关,调用
QModelIndex itemIndex = sourceModel()->index(source_row,i,source_parent);
if(!itemIndex.isValid())
continue;
PTSModelItem* item = static_cast<PTSModelItem*>(itemIndex.internalPointer());
The item returned is alway List1
or List2
, even with source_row being 0,1,2. 返回的项始终为
List1
或List2
,即使source_row为0,1,2。
Filling the model (listitem just holds text and a QList
of "childText"
: 填充模型(列表项仅包含文本和
QList
的"childText"
:
QStandardItemModel *model = new QStandardItemModel();
QStandardItem *rootItem = model->invisibleRootItem();
foreach(PTSItem* listItem, modelItemList)
{
PTSModelItem *item = new PTSModelItem(tr("List: %1").arg(listItem->getListNumber()),listItem,0,PTSModelItem::ITEM_TYPE_LISTNUMBER);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
rootItem->appendRow(item);
PTSModelItem *identTitle = new PTSModelItem("",listItem,0,PTSModelItem::ITEM_TYPE_IDENTEMPTY);
identTitle->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
rootItem->setChild(item->row(),1,identTitle);
PTSModelItem *readDateItem = new PTSModelItem(tDateString,listItem,0,PTSModelItem::ITEM_TYPE_CREATED);
readDateItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
rootItem->setChild(item->row(),2,readDateItem);
PTSModelItem *writeDateItem = new PTSModelItem(tDateString,listItem,0,PTSModelItem::ITEM_TYPE_LASTSET);
writeDateItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
rootItem->setChild(item->row(),3,writeDateItem);
for(int i=0; i<listItem->size();i++)
{
QList<QStandardItem*> childItems;
PTSModelItem *toolItem = new PTSModelItem(tr("T%1").arg(listItem->getToolNumber(i)),listItem,i,PTSModelItem::ITEM_TYPE_TOOLNUMBER);
toolItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
childItems.append(toolItem);
PTSModelItem *identItem = new PTSModelItem(listItem->getIdentNumber(i),listItem,i,PTSModelItem::ITEM_TYPE_IDENTNUMBER);
identItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
childItems.append(identItem);
PTSModelItem *readDate = new PTSModelItem("",listItem,i,PTSModelItem::ITEM_TYPE_CREATEDVALID);
readDate->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
childItems.append(readDate);
PTSModelItem *writeDate = new PTSModelItem("",listItem,i,PTSModelItem::ITEM_TYPE_LASTSETVALID);
writeDate->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
childItems.append(writeDate);
item->appendRow(childItems);
}
}
Filter implementation: 过滤器实现:
bool PTSFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QModelIndex itemIndex = sourceModel()->index(source_row,0,source_parent);
if(!itemIndex.isValid())
return false;
PTSModelItem* item = static_cast<PTSModelItem*>(itemIndex.internalPointer());
QString text = item->text(); // THIS always return ListN
if(item->type() == QStandardItem::Type)
{
if(item == static_cast<QStandardItemModel*>(sourceModel())->invisibleRootItem())
return true;
}
//Custom filtering starts here but breaks, since item is always only the List-element
}
QStandardItemModel requires you to not use the internalPointer()
method but QStandardItemModel要求您不要使用
internalPointer()
方法,而是
QStandardItemModel::itemFromIndex()
So problem solved by changing item retrieval in filterAcceptsRow to: 因此,通过将filterAcceptsRow中的项目检索更改为解决了以下问题:
PTSModelItem* item = static_cast<PTSModelItem*>(static_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(usedIndex));
The answer is mapToSource . 答案是mapToSource 。
QModelIndex QSortFilterProxyModel::mapToSource(const QModelIndex &proxyIndex) const
Example usage : 用法示例 :
QModelIndex realIndex = mapToSource(index);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.