PDA

View Full Version : Model with two very different views



mholmes
7th April 2010, 00:32
I'm trying to imagine how to implement a rather unusual model/view situation. I'm trying to provide two distinct views of an XML hierarchy:

1. A hierarchical tree view, using QTreeView.

2. A list view, based on QStringListModel, which shows a list of the nodes which have xml:id attributes, along with some text from those nodes, displayed in a QListView.

I can do each of these things separately -- in other words, I can implement a model based on QAstractItemModel, construct a tree in it, and display the tree in a QTreeView; and I can construct a model based on QStringListModel consisting of a list of the xml:ids, and display this in a QListView. But what I'd really like to do is have a single model which is hooked up to both a QTreeView and a QListView, so that any change to the model is simultaneously displayed in both controls.

Is this possible? If so, how would you go about it?

All help appreciated,
Martin

faldzip
7th April 2010, 07:36
Use a proxy model, either QSortFilterProxyModel (or derive a class from it) or make your own proxy model from scratch by subclassing QAbstractProxyModel.
This proxy model is between a model and a view, so in your case it will filter out any other nodes than xml:id from your base XML model.
In Qt docs you can found two examples demonstrating use of QSortFilterProxyModel.

Edit:
After taking a look on the QSortFilterProxyModel, I think that QSortFilterProxyModel::filterAcceptsRow() and QSortFilterProxyModel::filterAcceptsColumn() can be methods you want. They are virtual protected so you will need to subclass QSortFilterProxyModel, so take a look at Custom Sort/Filter Model example.

mholmes
7th April 2010, 16:01
You're right, that's the way to go; but I'm already using a QSortFilterProxyModel to enable the user to filter the QStringListModel content based on regular expressions. Can you chain together multiple QSortFilterProxyModels (i.e., originalSource->QSortFilterProxyModel to produce item list->QSortFilterProxyModel to allow user filtering)?

Cheers,
Martin

mholmes
7th April 2010, 23:19
I've done this, but I'm encountering a problem. My core model is a DomModel object, taken directly from the SimpleDomModel example. That works well with the tree view. Then I'm using my own QSortFilterProxyModel descendant to filter the output, like this:

bool HcmcXmlIdFilter::filterAcceptsRow ( int source_row, const QModelIndex &source_parent ) const{
DomItem *parentItem;

if (source_parent.isValid()){
parentItem = static_cast<DomItem*>(source_parent.internalPointer());
DomItem *childItem = parentItem->child(source_row);
if (childItem){
QDomNode n = childItem->node();
if (n.isElement()){
if (n.toElement().hasAttribute("xml:id")){
return true;
}
}
}
}
return false;
}

However, no content is showing up in the QListView. Even when I set that function to return true by default, only the top level elements show up in the list; child elements in the tree do not seem to be processed. Any suggestions as to what I'm doing wrong?

Cheers,
Martin