[Solved] Questions about QAbstractItemModel and Q(List/Tree)View
-
I recently posted a proxy model class here on the wiki that can filter trees. It does not flatten the list, but instead keeps parent nodes that have children that match (and keep child nodes where the parent matches). Perhaps that would be of use?
Note that it is meant for use on relatively small, simple tree models. Using it on a QFileSystemModel would result in less than satisfactory results, I bet.
-
I am back!
Thank you all for helping me guys! I managed to do what I wanted by overriding QAbstractProxyModel::mapToSource() and QAbstractProxyModel::mapFromSource() methods. It wasn't that hard after all! I just needed to understand good how the whole thing works! I did a simple implementation and it works fine! Hopefully I won't encounter any other difficulties now! Thanks again!
Cheers
-
I had a similar issue. I solved it by using KDescendantsProxyModel from KDE. Other than commenting out two lines related to kdebug() and including kbihash_p.h, it worked great. :-)
source: http://websvn.kde.org/trunk/KDE/kdepimlibs/akonadi/?pathrev=1217600
api-ref: http://api.kde.org/4.6-api/kdepimlibs-apidocs/akonadi/html/classKDescendantsProxyModel.html -
Hey Bekos
I have same thing to do for my work
@
-A
-A1
-A2
-B
-B1
-B2
@And I want to list the leaf items in the QListView:
@
-A1
-A2
-B1
-B2
@could you please help me out how could you solve this problem or share any peace of code for it
Thanks
-
I would adapt the KDescendantsProxyModel class referenced above for that. You can add a new role NodeLevelRole, and have the data() method return an integer representing the original level. So, in your case, node A and B would return 0 for this role, and A1, A2, B1 and B2 would return 1.
The next step is then to create a simple proxy model that filters based on the NodeLevelRole.
-
Thanks for reply Andre but i couldn't use these classes for some reasons i have my own implementation of Proxy Model class i have even re implement the filterAcceptsRow function right now if i click on A from above mention then all child of A will be shown in QList View and i have added search box in list view there i can type A1 so all A1 will be visible in list view and rest will be not but i need to show all child at one point of click say ALL so seeking for the work around for it
For your reference my current implementation
@
bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
QString checkStr = sourceModel()->data(index, Qt::DisplayRole).toString();
return ShowThis(index);
}bool MySortFilterProxyModel::ShowThis(const QModelIndex index) const
{
bool retVal = false;
//Gives you the info for number of childs with a parent
if ( sourceModel()->rowCount(index) > 0 )
{
for( int nChild = 0; nChild < sourceModel()->rowCount(index); nChild++)
{
QModelIndex childIndex = sourceModel()->index(nChild,0,index);
if ( ! childIndex.isValid() )
break;
retVal = ShowThis(childIndex);
if (retVal)
{
break;
}
}
}
else
{
QModelIndex useIndex = sourceModel()->index(index.row(), 0, index.parent());
QString type = sourceModel()->data(useIndex, Qt::DisplayRole).toString();
//qDebug()<<"type is "<<type;
if ( ! type.contains(filterRegExp()))
{
retVal = false;
}
else
{
retVal = true;
}
}
return retVal;
}
@Edit: Please use @ tags around code sections; Andre
-
Could you please re-phrase your question, this time using punctuation and separate sentences? I have a very hard time reading your question. Note that I have added some @ tags around your code to make that readable. Please do that yourself next time.
-
Sorry for that i have first time post here so don't know this, i will take care of this from next time
I will not use these KDescendantsProxyModel class for some reasons,
I have my own implementation of Proxy Model class, & re-implement already filterAcceptsRow
function for filter specific to parent in QListView.I have QAbstractItemModel implementation which share in two view [ QTreeView & QListView]
Scenario - 1
Click on QTreeView any of parent item i emit the signal and set root index of list view with that clicked index so all child with respect to that parent will show in list view.There is search box [QLineEdit] in which i type any char so according to this list view hide and show the items.
......This works fine for me
Now i have combo box in list view which contains list of parent items of tree view with check box
and ALL option as well , so when click on particular parent item and check it true in that combo box from list view it will fetch that child items from list view as i mention above set root index to list view and show them in list.But when i click on ALL i need to get all child's to list in list view but i can set root index to list view only one , ........ so how could it possible ?
Also if i seek tree view root and find index of it and set it to list view then it will list the all parent items instead of it i will try to list all child's of that all parent items to be list.
For that search box implementation please look that code
@
bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
QString checkStr = sourceModel()->data(index, Qt::DisplayRole).toString();
return ShowThis(index);
}bool MySortFilterProxyModel::ShowThis(const QModelIndex index) const
{
bool retVal = false;
//Gives you the info for number of childs with a parent
if ( sourceModel()->rowCount(index) > 0 )
{
for( int nChild = 0; nChild < sourceModel()->rowCount(index); nChild++)
{
QModelIndex childIndex = sourceModel()->index(nChild,0,index);
if ( ! childIndex.isValid() )
break;
retVal = ShowThis(childIndex);
if (retVal)
{
break;
}
}
}
else
{
QModelIndex useIndex = sourceModel()->index(index.row(), 0, index.parent());
QString type = sourceModel()->data(useIndex, Qt::DisplayRole).toString();
//qDebug()<<"type is "<<type;
if ( ! type.contains(filterRegExp()))
{
retVal = false;
}
else
{
retVal = true;
}
}
return retVal;
}
@also i have tried with passing something like this proxy model
@
void ModelBrowser::mbUpdateListViewForFilterChanged( QString filterString )
{
if(filterString == "ALL")
{
QRegExp rx("[A-Za-z_]+([A-Za-z_0-9]*)");
proxy->setFilterRegExp(rx);
}
else
{
QRegExp::PatternSyntax syntax = QRegExp::RegExp;Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
QString strPattern = "^" + filterString;
QRegExp regExp(strPattern, caseSensitivity);proxy->setFilterRegExp(regExp);
}
}
@but still it didn't work .....
Thank
Prashant -
Hello pmoglaikar,
Unfortunately I won't be able to help much. I deleted the code of my iplementation a week after writing it. And since then, I never touched Qt again. :( As a result I remember almost nothing. What I remember is that in order to flatten my tree to a view (i.e. list only the child nodes ignoring all parents) I had to use QAbstractProxyModel::mapToSource() and QAbstractProxyModel::mapFromSource(). What you actually do in these methods is to "translate" a QModelIndex to another QModelIndex. A1 and B1 in the Tree have both Row id 0. But in the list they have row id 0 and 2 respectively. Override functions above to do this "translation".
Keep in mind that there is a high chance I am talking nosense. I don't remember much. I haven't touched Qt for a while now.Cheers,
George[quote author="pmoglaikar" date="1335428929"]Hey Bekos
I have same thing to do for my work
@
-A
-A1
-A2
-B
-B1
-B2
@And I want to list the leaf items in the QListView:
@
-A1
-A2
-B1
-B2
@could you please help me out how could you solve this problem or share any peace of code for it
Thanks [/quote]
-
Hi Andre,
Any help now i am still struggling to get it done ?
Thanks
Prashant -
Hi Andre,
Any help now i am still struggling to get it done ?
Thanks
Prashant
[quote author="Andre" date="1335508912"]Could you please re-phrase your question, this time using punctuation and separate sentences? I have a very hard time reading your question. Note that I have added some @ tags around your code to make that readable. Please do that yourself next time.[/quote]