Flat leaf Proxy
-
wrote on 29 May 2015, 09:38 last edited by VRonin
I have a model (QStandardItemModel actually) with a list of data (10 columns) each row data contains the sum off all children items. so it's a very basic tree with just one level. now I'd like to display all child items of all the tree nodes in a flat table. To achieve it I thought about a ProxyModel. Here is what I did:
#ifndef CHILDTABLEPROXY_H #define CHILDTABLEPROXY_H #include <QAbstractProxyModel> class ChildTableProxy : public QAbstractProxyModel { Q_OBJECT public: ChildTableProxy(QObject *parent); virtual QModelIndex mapToSource(const QModelIndex& proxyIndex) const override; virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; virtual bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex())override; virtual bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex())override; virtual bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex())override; virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex())override; virtual QItemSelection mapSelectionToSource(const QItemSelection& selection) const override; virtual QItemSelection mapSelectionFromSource(const QItemSelection& selection) const override; virtual QModelIndex parent(const QModelIndex& child) const override; virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex & proxyIndex, int role = Qt::DisplayRole) const override; protected: virtual QModelIndex getSourceIndex(int row, int column) const; }; #endif // CHILDTABLEPROXY_H
#include "ChildTableProxy.h" #include <QItemSelection> ChildTableProxy::ChildTableProxy(QObject *parent) : QAbstractProxyModel(parent) {} QModelIndex ChildTableProxy::mapFromSource(const QModelIndex& sourceIndex) const { if (!sourceIndex.isValid()) return QModelIndex(); if (!sourceIndex.parent().isValid()) return QModelIndex(); int row = sourceIndex.row(); for (int i = 0; i < sourceIndex.parent().row(); ++i) row += sourceIndex.model()->rowCount(sourceIndex.model()->index(i, 0)); return index(row, sourceIndex.column()); } int ChildTableProxy::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; int result = 0; for (int i = 0; i < sourceModel()->rowCount();++i){ result += sourceModel()->rowCount(sourceModel()->index(i, 0)); } return result; } int ChildTableProxy::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return sourceModel()->columnCount(); } bool ChildTableProxy::insertColumns(int, int, const QModelIndex&) { return false; } bool ChildTableProxy::insertRows(int , int , const QModelIndex&) { return false; } bool ChildTableProxy::removeColumns(int , int , const QModelIndex& ) { return false; } bool ChildTableProxy::removeRows(int , int , const QModelIndex& ) { return false; } QItemSelection ChildTableProxy::mapSelectionToSource(const QItemSelection& selection) const { QItemSelection result; const QModelIndexList allSelected = selection.indexes(); for (auto i = allSelected.constBegin(); i != allSelected.constEnd(); ++i) { const QModelIndex mapped = mapToSource(*i); result.select(mapped, mapped); } return result; } QItemSelection ChildTableProxy::mapSelectionFromSource(const QItemSelection& selection) const { QItemSelection result; const QModelIndexList allSelected = selection.indexes(); for (auto i = allSelected.constBegin(); i != allSelected.constEnd(); ++i) { const QModelIndex mapped = mapFromSource(*i); result.select(mapped, mapped); } return result; } QModelIndex ChildTableProxy::parent(const QModelIndex&) const { return QModelIndex(); } QModelIndex ChildTableProxy::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid()) return QModelIndex(); QModelIndex sourceIdx = getSourceIndex(row,column); if(!sourceIdx.isValid()) return QModelIndex(); return createIndex(row, column, sourceIdx.internalPointer()); } QVariant ChildTableProxy::data(const QModelIndex & proxyIndex, int role) const { return sourceModel()->data(mapToSource(proxyIndex),role); } QModelIndex ChildTableProxy::getSourceIndex(int row, int column) const { if (row < 0 || column < 0 || column >= columnCount()) return QModelIndex(); for (int i = 0; i < sourceModel()->rowCount(); ++i) { if (row >= sourceModel()->rowCount(sourceModel()->index(i, 0))) row -= sourceModel()->rowCount(sourceModel()->index(i, 0)); else return sourceModel()->index(row, column, sourceModel()->index(i, 0)); } // row>rowCount() return QModelIndex(); } QModelIndex ChildTableProxy::mapToSource(const QModelIndex& proxyIndex) const { if (!proxyIndex.isValid()) return QModelIndex(); if (proxyIndex.parent().isValid()) return QModelIndex(); return getSourceIndex(proxyIndex.row(), proxyIndex.column()); }
Unfortunately, despite rowcount returning the correct number, data is never called with a row greater than 0. What am I doing wrong?
Thanks in advance -
wrote on 5 Jun 2015, 21:56 last edited by
How are you viewing the model?