13.4.  Tree Models

[ fromfile: treemodels.xml id: treemodels ]

  1. QAbstractItemModel is a general-purpose abstract model used with QTreeView, QListView, or QTableView.

  2. QStandardItemModel, used in Example 13.2 is a concrete class that can store QStandardItems, making it convenient to populate a concrete model with tree nodes.

  3. QTreeWidgetItem is not a model class, but can build trees in a QTreeWidget, derived from QTreeView.

Figure 13.12.  ObjectBrowser Tree

ObjectBrowser Tree

Example 13.21. src/modelview/objectbrowser/ObjectBrowserModel.h

[ . . . . ]
#include <QAbstractItemModel>
class ObjectBrowserModel :public QAbstractItemModel {
 public:
    explicit ObjectBrowserModel (QObject* rootObject);
    int columnCount ( const QModelIndex& parent = QModelIndex() ) const;
    int rowCount ( const QModelIndex& parent = QModelIndex() ) const;
    QVariant data ( const QModelIndex& index, 
                    int role = Qt::DisplayRole ) const;
    QVariant headerData(int section, Qt::Orientation, 
                        int role = Qt::DisplayRole) const;
    QModelIndex index ( int row, int column, 
                        const QModelIndex& parent = QModelIndex()) const;
    QModelIndex parent ( const QModelIndex& index ) const;

 protected:
    QList<QObject*> children( QObject* parent ) const;
    QString label( const QObject* widget, int column ) const;
    QObject* qObject( const QModelIndex& ) const;
 private:
    QObject *rootItem;
};
[ . . . . ]

Example 13.22. src/modelview/objectbrowser/ObjectBrowserModel.cpp

[ . . . . ]

QModelIndex ObjectBrowserModel::
index(int row, int col, const QModelIndex& parent) const {
    if ((row < 0) || (col < 0) || row >= rowCount() || 
        col >= columnCount()) return QModelIndex();
    return createIndex( row, col, qObject(parent) ); 1
}

QModelIndex ObjectBrowserModel::parent( const QModelIndex& index ) const {
    if (!index.isValid()) return QModelIndex();
    QObject* obj = qObject(index)->parent();         2
    if ( obj == 0 )
        return QModelIndex();

    QObject* parent = obj->parent();
    int row = children( parent ).indexOf( obj );
    return createIndex( row, 0, parent );
}

QObject* ObjectBrowserModel::
qObject(const QModelIndex& index) const {            3
    if ( index.isValid() ) {
        QObject* parent = reinterpret_cast<QObject*>( index.internalPointer() );
        return children(parent)[index.row()];        4
    }
    return 0;                                        5
}

1

Store an internalPointer in the index.

2

qObject() returns the row child of this index but you want this index's parent QObject pointer which is stored in index.internalPointer().

3

My index's internalPointer is my parent QObject pointer. I am the row() child of my parent.

4

This is me!

5

This is the root.