QSortFilterProxyModel -filterAcceptsRow()- filter parent Node and child Node
-
Hi xcround,
I am not clear , are you trying to filter parent as well as child?
I have accomplished this and here is the logic,
@def filterAcceptsRow(self,sourceRow,sourceParent):
if super(MySortFilterProxyModel,self).filterAcceptsRow(sourceRow,sourceParent):
return True
return self.hasAcceptedChildren(sourceRow,sourceParent)def hasAcceptedChildren(self,sourceRow,sourceParent):
model=self.sourceModel()
sourceIndex=model.index(sourceRow,0,sourceParent)
if not sourceIndex.isValid():
return False
indexes=model.rowCount(sourceIndex)
for i in range(indexes):
if self.filterAcceptsRow(i,sourceIndex):
return True
return False@
-
Here is the what I have now, but still is not filtering the parents and child.
@
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)
{
....
if (!action.isEmpty())
{QModelIndex index = sourceModel()->index(sourceRow, ACTION, sourceParent); if (hasAcceptedChildren(sourceRow, sourceParent)) return true; if (action != sourceModel()->data(index).toString()) return false; } return true;
}
bool TableProxy::filterAcceptsRowItself(int sourceRow, const QModelIndex &sourceParent) const
{
return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}bool TableProxy::hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const
{
QModelIndex item = source_parent;
if (!item.isValid())
{
qDebug() << "item invalid" << source_parent.data().toString() << source_row;
return false;
}
int childCount = item.model()->rowCount(item);if (childCount == 0) return false; for (int i = 0; i < childCount; ++i) { if (filterAcceptsRowItself(i, item)) return true; //recursive call if (hasAcceptedChildren(i, item)) return true; } return false;
}
@
Thanks for the help -
Hi xcround,
please make changes in your code according this python code and i am sure it will filter parent as well as child .
@
def filterAcceptsRow(self,sourceRow,sourceParent):
if super(MySortFilterProxyModel,self).filterAcceptsRow(sourceRow,sourceParent):
return True
return self.hasAcceptedChildren(sourceRow,sourceParent)def hasAcceptedChildren(self,sourceRow,sourceParent):
model=self.sourceModel()
sourceIndex=model.index(sourceRow,0,sourceParent)
if not sourceIndex.isValid():
return False
indexes=model.rowCount(sourceIndex)
for i in range(indexes):
if self.filterAcceptsRow(i,sourceIndex):
return True
return False@ -
Hi xcround,
I think in your case it would be some thing like this needs to be......
( i am not a c/c++ guy)
@
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)
{
....
if (!action.isEmpty())
{
if (QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent))
{
return true
}
return hasAcceptedChildren(sourceRow, sourceParent)
}
.........
}bool TableProxy::hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const
{
QModelIndex item = source_parent;
if (!item.isValid())
{
qDebug() << "item invalid" << source_parent.data().toString() << source_row;
return false;
}
int childCount = item.model()->rowCount(item);if (childCount == 0) return false; for (int i = 0; i < childCount; ++i) { if (filterAcceptsRow(i, item)) return true; } return false;
}@
-
Sorry but from mine understanding I first need to check if the string matches the one I'm looking for.
So that's why I have the first if statement, and then I do what you said in the previous post.
@
f (!action.isEmpty())
{
QModelIndex index = sourceModel()->index(sourceRow,
ACTION, sourceParent);if (action != sourceModel()->data(index).toString()) return false; if ((QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent))) return true; return hasAcceptedChildren(sourceRow, sourceParent); }
@
Still trying to understand whats going wrong. -
Hi qties,
at the first time I read the post from André I was so happy to find the solution I am searching for.
But unfortunately I am to stupid to get it work. Maybe you can help me.If I use the standard QSortFilterProxyModel everything works good except the search at textChanged Signal.
But if I use the LeafFilterProxyModel (exactly as André has post it) an error occurs and I do not know what it means.I hope somebady can help me.
Thank you.@
LeafFilterProxyModel m_oProxyModel;
//QSortFilterProxyModel m_oProxyModel;
QStandardItemModel m_oItemModel; // manualy filledm_oProxyModel.setSourceModel(&m_oItemModel);
m_tvDBC->setModel(&m_oProxyModel); // TreeView
m_lvDBC->setModel(&m_oStringModel); // ListView
@@
void cClass::textChanged(QString text)
{
QRegExp::PatternSyntax pSyntax = QRegExp::PatternSyntax(QRegExp::FixedString);
QRegExp regExp(text, Qt::CaseInsensitive, pSyntax);m_oProxyModel.setFilterRegExp(regExp);
m_oProxyModel.setFilterKeyColumn(-1);
}
@@
Error 1 error LNK2001: unresolved external symbol "public: __thiscall
LeafFilterProxyModel::LeafFilterProxyModel(class QObject *)"
??0LeafFilterProxyModel@@QAE@PAVQObject@@@Z) myobject.obj
@ -
-
There was an unfortunate bug at the time in DevNet, that sometimes inserted ; at the wrong places in code sections. The code listing I posted suffered from this. The argument is supposed to be a single argument source_parent. I'll try to fixup the original posting. Thanks for noticing.
-
Thank you - this thread has been really helpful!
-
Esta implementación recorre todo los sub-Nodos del padre buscando que el filterRegExp coincida con el Qt::DisplayRole del sub-Nodo.
El algoritmo no utiliza recursividad :D
@bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QList<QModelIndex> children;
children << sourceModel()->index(source_row, 0, source_parent);bool show = false; for(int i = 0; i < children.length(); i++) { if(show) break; // Add sub Nodos // for(int c = 0; c < sourceModel()->rowCount(children[i]) ;c++) children.append(children[i].child(c,0)); QString type = sourceModel()->data(children[i], Qt::DisplayRole).toString(); show = type.contains(filterRegExp()); } return show;
}@