PDA

View Full Version : Model-View



MTK358
8th August 2010, 18:31
Can someone help me understand Qt's model-view system?

I partially understand how to make models for lists and tables, but I don't get trees. Also, I don't understand what the delegate is.

Lykurg
8th August 2010, 19:14
A delegate is only for rendering a "item" to the view. You can say that a delegate is only the paint event for the item. So you have three parts:

the model: it contains all data without any information how and where it is displayed.
the view: It defines where the widget should be shown and in which way (list, table, tree)
the delegate: it paints the item/data to the space, which is defined by the model.

What do you don't get with the tree model?

MTK358
8th August 2010, 19:20
A delegate is only for rendering a "item" to the view.

So it's basically an "item renderer"?


What do you don't get with the tree model?

I don't get how the tree structure itself is constructed.

Lykurg
8th August 2010, 19:25
So it's basically an "item renderer"?
yes.

I don't get how the tree structure itself is constructed.
it is all about patents and children. first you have an item A. that item can have children, for example item A1, A2 and A3. these three items gets expanded when you click item A:
+ item A (parent)
after clicking:
+ item A
- item A1 (child)
- item A2 (child)
- item A3 (child)thats all. Now item A1 also can be a parent of other items and so on and so on. The whole tree has one invisible root item. That's all.

MTK358
8th August 2010, 19:34
I understand what a tree structure is, but I don't understand how Qt represents it internally using QModelIndex.

Also, why are they called "Delegates"?

Lykurg
8th August 2010, 19:40
but I don't understand how Qt represents it internally using QModelIndex. A model index can have a parent. See http://doc.trolltech.com/latest/model-view-model.html#parents-of-items
QModelIndex::parent()

QModelIndex::child()


Also, why are they called "Delegates"?Who are they? Where is a model called delegate?

MTK358
8th August 2010, 19:43
A model index can have a parent. See http://doc.trolltech.com/latest/model-view-model.html#parents-of-items
QModelIndex::parent()

QModelIndex::child()

So every QModelIndex (aka row) has a parent index? I'm really confused how this can work.


Who are they? Where is a model called delegate?

I meant "Why are 'Delegates' called that"?

Lykurg
8th August 2010, 19:51
So every QModelIndex (aka row) has a parent index?
Yes every QModelIndex has a parent, only the root item will give QModelIndex() back, so that is the only item without a parent.

I'm really confused how this can work.
Well, there are examples that it works:D


I meant "Why are 'Delegates' called that"?Ehm, ok, that was what you wrote, but sometime my english fails:mad:
And only the Trolls know why they called them delegates. Maybe because the painting (representation) of the data is delegated to them.

MTK358
8th August 2010, 19:55
What kind of data does a QModelIndex store?

Lykurg
8th August 2010, 20:01
What kind of data does a QModelIndex store? No data at all. All the data lies in the model. the QModelIndex is only a "pointer". Therefore an index is bound to a model: QModelIndex::model(). All data is in the model. the index identifies the data in the model. the view arrange the "items" on the screen and the delegate actually paints the items using the data from the model.

So all information in an index are (shortend): the model, the "data storing location" of the specified item inside the model.

MTK358
8th August 2010, 20:09
So a QModelIndex contains a row, column, and a parent QModelIndex?

And is the row and column relative to the current node, not the root node?

Lykurg
8th August 2010, 20:14
So a QModelIndex contains a row, column, and a parent QModelIndex? yes, and the model of course.


And is the row and column relative to the current node, not the root node?If you mean the "direct parent" with "current node", then yes.

MTK358
8th August 2010, 21:34
But there's only one model, there's not a separate model for each level of the hierarchy, right?

Lykurg
8th August 2010, 23:12
But there's only one model, there's not a separate model for each level of the hierarchy, right?
yes. There is also an example of creating a tree model in the docs: Simple Tree Model Example.

MTK358
9th August 2010, 03:05
I decided to look at the example, but, for example, I don't have a clue what this does or how it should work:

QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
const
{
if (!hasIndex(row, column, parent))
return QModelIndex();

TreeItem *parentItem;

if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());

TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}

MTK358
10th August 2010, 15:52
Can anyone answer?

MTK358
15th August 2010, 19:22
OK, I kind of get it now, but I have two questions:


Why does QModelIndex's child() function take a row and a column? I thought only rows have children?!?!?
Given a QModelIndex, how would you use it to get the appropriate item from your internal data representation, whether they are objects containing a data item and a list of children, or a list of items, each one containing the index of it's parent?

ChrisW67
16th August 2010, 00:27
Any item can have children although I suspect would be unusual to have children on items in any column except the first. The data is still present and can be retrieved by a custom view class, for non-viewing purposes, or by calling QTreeView::setRootIndex().


#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QStandardItemModel model;
QStandardItem *parentItem = model.invisibleRootItem();
// Build simple tree with two columns
// children are in col 0
for (int i = 0; i < 4; ++i) {
QList<QStandardItem *> items;
items.append( new QStandardItem(QString("item %0 col 0").arg(i)) );
items.append( new QStandardItem(QString("item %0 col 1").arg(i)) );
parentItem->appendRow(items);
parentItem = items.at(0);
}

// Add some children under the first row's col 1 as well
parentItem = model.item(0, 1);
for (int i = 0; i < 3; ++i) {
QList<QStandardItem *> items;
items.append( new QStandardItem(QString("surprise %0").arg(i)) );
items.append( new QStandardItem(QString("surprise %0").arg(i)) );
parentItem->appendRow(items);
parentItem = items.at(0);
}

// Show the usual hierarchy
QTreeView view1;
view1.setModel(&model);
view1.show();

// Show hierarchy under the item at (0,1)
QTreeView view2;
view2.setModel(&model);
view2.setRootIndex(model.index(0,1, QModelIndex()));
view2.show();

return app.exec();
}

MTK358
16th August 2010, 03:09
OK, what about the second question in my previous post?

ChrisW67
16th August 2010, 11:00
That's entirely up to you. You need to devise some mapping between rows and columns and the elements in your data structure(s) and implement the data(), setData(), index() etc. methods accordingly. For lists the row number could map directly to a list index. Have a read in the wiki QAbstractItemModel as well as this forum and the Qt docs

grabalon
16th August 2010, 19:46
QMap may help.