Model-view: Display items in different ways
I use the Model/View architecture for creating a tree-based structure. The model consists of nodes which can be of several different types.
The tree can look like this:
Root (type a)
child1 (type a)
child2 (type b)
child3 (type a)
Now what I want is to present type a and type b in different ways, say a is supposed to be a circle and b a rectangle.
What is the "correct" way for doing this?
I was thinking about using item roles to define the types. Say type a nodes respond that they are of "a" type when the TypeRole is fetched via the data()-function. Drawing then depends on this role's role, or data. That is, the data()-function for the TypeRole returns a new role that then defines how to draw the node.
Example:
Code:
// We have this in the model
// Getting the Type is via
int TypeRole = 34; //Available ItemDataRole
// Types are
int rootType = root.data(TypeRole);
int child1Type = child1.data(TypeRole);
int child2Type = child2.data(TypeRole);
int child3Type = child3.data(TypeRole);
// rootType == child1Type = child3Type == TYPE_A
// rootType != child2Type == TYPE_B
// How I thought of doing this is:
// Go through nodes and draw them
int childCount = model()->rowCount(index);
for ( int childNum=0; childNum < childCount; childNum++)
{
// Get the child and draw it
QModelIndex child
= model
()->index
( childNum,
0, root
);
// Get the type
int type = child.data( TypeRole );
//Draw them depending on the type
switch (type)
{
case (TYPE_A):
drawTypeA(child); //Draws the rectangle
break;
case (TYPE_B):
drawTypeB(child); //Draws the circle
break;
}
}
Is this how this is "supposed" to be done, or should the roles instead be directly used, so that drawing draws something only if the node is of correct type?
Code:
//We have several ItemDataRoles defined
int TypeARole = 34;
int TypeBRole = 35;
drawNode( child.data( TypeARole ) ); //Draws a rectangle, but only for A-type nodes
drawNode( child.data( TypeBRole ) ); //Draws a circle but only for B-type nodes
Or are there other better alternatives?
Re: Model-view: Display items in different ways
Quote:
Originally Posted by
taboom
[/code]Is this how this is "supposed" to be done, or should the roles instead be directly used, so that drawing draws something only if the node is of correct type?
Code:
//We have several ItemDataRoles defined
int TypeARole = 34;
int TypeBRole = 35;
drawNode( child.data( TypeARole ) ); //Draws a rectangle, but only for A-type nodes
drawNode( child.data( TypeBRole ) ); //Draws a circle but only for B-type nodes
Or are there other better alternatives?
I'm guessing that this last piece of code is part of a custom view and not somehow part of the model...
I think your on the right track with your primary description of discriminating in the data() method. The only minor thing I do differently is contain the "type" in my item node instead of a custom role. Just a personal preference.
Mind you, I'm not an expert yet though. -travlr
Re: Model-view: Display items in different ways
The correct way is to implement a custom delegate (subclass of QAbstractItemDelegate or QItemDelegate) that will be able to determine if a particular index if of type A or B and handle the item accordingly.
Re: Model-view: Display items in different ways
Ok, I guess this was what I was looking for :) Thanks!