PDA

View Full Version : Building a model from an item's children...



graffy
17th February 2014, 17:20
Hello,

I have a QStandardItemModel structure that I've set up to be displayed in a tree view. The first item of each record contains several children, with each child having multiple children of it's own.

Thus, the tree structure looks something like:

Top-Level Reccord 1
| ----> Record-level list 1
| ----> Record-level list 2
| ----> List-level item 1
| ----> List-level item 2
| ----> Record Level list 3
Top-Level Record 2
Top-Level Record 3
...

It's easiest to think of it as each record having several different lists of information, thus the first-level children described the list name / type, and the second level children are the list items.

What I want to do is create a proxy model that operates *only* on one set of second-level children (a model that manipulates list items directly).

For example, if I have a record with three lists, and I want to create a model that manages the items in the second list, I should be able to write something like:



MyListProxyModel listProxyModel();
listProxyModel.setSourceModel (mainModel);

QStandardItem secondListItem = mainModel.item(0, 0)->child(1);
QModelIndex secondListIndex = mainModel.indexFromItem (secondListItem);

listProxyModel.setRootIndex (secondListIndex);

qDebug() << "The second list has " << listProxyModel.rowCount() << " records...";


Output: "The second list has 2 records..." (assuming above example structure).

I can think of a way to implement this in a custom proxy model, but it's not a very appealing approach, and I'd rather not write a custom class to encapsulate this functionality if I don't have to.

Is there a reasonably clean way to go about accomplishing this?

ChrisW67
17th February 2014, 20:48
Are you doing this to get a tree subset to display in a tree view? Does QAbstractItemView::setRootIndex() scratch your itch?

graffy
17th February 2014, 21:52
Not quite. I'm actually creating a UI framework that's scriptable at runtime. The top-level data describes the layout information loaded from the script, and the child lists are the actual model data that I want to manipulate with the UI widgets. Really, it's two separate models that I'm combining into one - the top-level data declares the UI, the child data is the actual data I want to manipulate.

Originally, I had these represented as two separate models. I combined them because a tree view provided a nice way to be able to inspect the loaded data all at once for script debugging purposes. Maybe I'm just making this harder than it needs to be...

So to answer the question, no. I want a QAbstractItemModel way of doing what you can do with QAbstractItemView, I guess...

My only solution at this point is to create a secondary model which pushes / pulls this list data to / from the primary model. I'd much rather do it with a QSortFilterProxyModel, for example, but unless there's an intrinsic way to filter only the children of a particular index / item, i'm not sure how to get it done without a lot of hassle.

anda_skoa
18th February 2014, 10:02
Another approach would be to have two models working on the same data, just displaying different portions.

You are currently using QStandardItemModel which is both the model and the data store, but if you have your data in some application data structures it should be possible to use models just as interfaces.

Cheers,
_

graffy
18th February 2014, 12:01
"You are currently using QStandardItemModel which is both the model and the data store, but if you have your data in some application data structures it should be possible to use models just as interfaces."

I think that's what I've settled on doing. The child items are built off of a QStringList, so I'll save that list in the parent item as Qt::UserRole data, then retrieve it as needed. Should be fairly simple to get / set the list to / from the item and cause the child items to be rebuilt whenever the parent list is set...

Thanks for the ideas!