Layered Views
-
I have two classes that look like this:
struct parent { QList<child> children; }; struct child { int id; };
I now want to represent those two classes in two views that are next to each other.
Selecting aparent
in the left view should show all of its children in the second view. I'm a bit unsure how to properly implement this. I created aQHash
fromparent
tochild_model
inparent_model
and then callingsetModel
for thechild_view
every time a newparent
is selected.The issue there is that the selection-state and expansion state (or rather in general the entire internal state of the
child_view
is reset, which isn't great UX wise)I'm looking for pointers on how to approach this. Should I map from
parent
tochild_view
instead?
Should I only have onechild_model
and a custom view that delegates itsindex
/parent
/etc. calls via the currently selectedparent
?Thanks in Advance
Folling -
So, no one has an answer for this?
I find it hard to believe I'm the first person trying to display a one-to-many relationship in qt.
Here's two approaches I came up with for now:
-
Have a map of
parent_model
tochild_model
somewhere, and exchange the model in the view usingQAbstractItemView::setModel
. -
store all children in
child_model
and allow the creation ofQProxyModel
that will then only display the relevant children
Both of these carry their own issues, so I find them subpar to an ideal solution.
The first doesn't retain things like expansion or selection state, the second is imperformant~ish. -
-
Hi,
So you have a list of
parent
struct containing a list ofchildren
struct ?Then you have have a main model on top of list of
parent
and have a filter proxy model that will return only the list of child to the second view and only the parents on the first view. -
So you have a list of parent struct containing a list of children struct ?
Indeed!
Then you have have a main model on top of list of parent and have a filter proxy model that will return only the list of child to the second view and only the parents on the first view.
So I have one model, that contains all data, and I construct proxy models of that, which only return the relevant data regarding some parameters (in this case, "only return the children of parent X")?
And a follow up question: If the model manages both
parent
andchild
objects - how would I go about handlinginsertRows
and such functionality? I could override it in the proxy model, but then I couldn't propagate the changes between multiple proxy models accessing the same data. -
Usually proxy models come between the main model and the view(s).
-
Pardon my intrusion, but that doesn't cover this part of the question for me:
And a follow up question: If the model manages both parent and child objects - how would I go about handling insertRows and such functionality? I could override it in the proxy model, but then I couldn't propagate the changes between multiple proxy models accessing the same data.
Or maybe I just overlooked it
-
It depends on how you intend to manage your data from your application point of view.
-
As said in the iniital post - I will have multiple views.
You have two list views next to each other - one for allparent
objects and one for the selected parent'schild
objects. The second view needs to be updated whenever a new parent is selected.
Parents and Children are accesed in multiple other points in the program, there is for example, also a tableview to look at all children of a parent in more detail. (Tableview uses custom delegates to allow users to make edits on the children in place).
Removal and addition of children can hence happen in any place where a list of children is displayed. -
I was rather thinking of the backend side of stuff like where do this data come from ? What generates them ?
-
I'll try to give as much concise information as I can:
The data is (almost always) generated by the user - an exception to this would be a shipped demo project, and in the future perhaps plugins.
Children only ever have one parent, but parents can have multiple children. So it's a true 1:n relationship.
The user can create parents, and assign children to them, as well as delete and reorder them.
Both parents and children are part of a project's state, which is persisted through multiple iterations using messagepack.You can load a project at any time, which would completely switch out the data the program is currently using - similar to how you'd be able to with word/pretty much any IDE.
Can't think of anything else that could be relevant - thanks for taking the time btw!