Reputation: 5892
I have the following simple model example:
#include <QtGui/QApplication>
#include <QtGui/QTreeView>
#include <QAbstractItemModel>
class TestModel : public QAbstractItemModel
{
public:
TestModel()
{
SetUpData();
}
virtual QModelIndex index(int row, int column, const QModelIndex& parent) const
{
if ( parent.isValid())
{
// child
return createIndex( row, column, (void*)&mData[row].mChildren[column]);
}
// root
return createIndex( row, column, (void*)&mData[row]);
}
virtual QModelIndex parent(const QModelIndex& child) const
{
ModelData* data = (ModelData*)child.internalPointer();
// find out where "data" is in the mData vector structure
for ( size_t i=0; i<mData.size(); ++i )
{
for ( size_t j=0; j<mData[i].mChildren.size(); ++j )
{
if ( &mData[i].mChildren[j] == data )
{
// I think this is correct, return the parent row at col 0?
return createIndex( i, 0, (void*)&mData[i].mChildren[j]);
}
}
}
return QModelIndex();
}
virtual int rowCount(const QModelIndex& parent) const
{
if ( parent.isValid() )
{
// Per root node size
return mData[parent.row()].mChildren.size();
}
// Root size
return mData.size();
}
virtual int columnCount(const QModelIndex& parent) const
{
// The "parent" nodes should have two columns, the children should have 1
if ( parent.isValid() )
{
// Root
return 1;
}
// Children
return 2;
}
virtual QVariant data(const QModelIndex& index, int role) const
{
if ( role == Qt::DisplayRole && index.isValid() )
{
if ( index.isValid() )
{
// I think col and row are the wrong way around, but will crash if swapped
return mData[index.column()].mChildren[index.row()].mName;
}
else
{
// this never happens because "RootN" is never displayed
return mData[index.column()].mName;
}
}
return QVariant();
}
private:
// The "real" data that this Qt model is providing an interface to
struct ModelData
{
QString mName;
std::vector< ModelData > mChildren;
};
std::vector< ModelData > mData;
void SetUpData()
{
for ( int i=0; i<3; ++i )
{
ModelData root;
root.mName = "Root" + QString::number( i+1 );
for ( int j=0; j<10; ++j )
{
ModelData node;
node.mName = "Node" + QString::number( j+1 );
root.mChildren.push_back( node );
}
mData.push_back( root );
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TestModel* model = new TestModel();
QTreeView* tv = new QTreeView();
tv->setModel( model );
tv->show();
int ret = a.exec();
delete tv;
delete model;
return ret;
}
What I'm trying to do here is create a model which has the following structure:
Root1
|-Node1-10
|
Root2
|-Node1-10
|
Root3
|-Node1-10
However I end up with this:
I'm really confused about how index/parent and data are supposed to be working. Obviously I don't understand it because my output is incorrect.
I thought that for example, Root1, Node3 would cause index to be called with row = 0, col=2, at which point I call createIndex with 0,2 and the pointer to that element?
And for parent() return QModelIndex if parent is valid as this means its a RootN element, then return createIndex to create an index to the parent if its not a root element.
Finally for data I figured this just returns the display string for the UI for the given row/column?
Upvotes: 0
Views: 4962
Reputation: 22356
I thought that for example, Root1, Node3 would cause index to be called with row = 0, col=2, at which point I call createIndex with 0,2 and the pointer to that element?
No. Your tree has only two columns: col 0 shows the tree hierarchy, and col 1 displays the labels again. So calling col 2 is just invalid.
Root1, Node3 should have a row=2 col=(1/2, whichever you wanted) and a parent index equal to row=0, col=(1/2) with an invalid parent (an invalid parent means you are at root level).
What data(..)
returns depends on what role
is passed to it, see the documentation for types you should be interested in.
Upvotes: 2