|Parent 1 -----Child 1 -----Child N |Parent N -----Child 1 -----Child N
Item1 Item2 Item3
|Parent 1 ------Child 1 ------Child N |Parent N ------Child 1 ------Child N |Item1 |Item2 |Item3
// QAbstractItemModel // Qt class ModelJoinerProxy : public QAbstractItemModel { Q_OBJECT public: ModelJoinerProxy(QObject *parent = 0); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &child) const; int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; // 1 virtual void setSourceModel1(QAbstractItemModel *sourceModel1); // 2 virtual void setSourceModel2(QAbstractItemModel *sourceModel2); // virtual QModelIndex mapToSource(const QModelIndex &) const; // virtual QModelIndex mapFromSource(const QModelIndex &) const; private slots: void source_dataChanged(QModelIndex, QModelIndex); void source_rowsAboutToBeInserted(QModelIndex p, int from, int to); void source_rowsInserted(QModelIndex p, int, int); void source_rowsAboutToBeRemoved(QModelIndex, int, int); void source_rowsRemoved(QModelIndex, int, int); void source_modelReset(); private: QAbstractItemModel *m1; QAbstractItemModel *m2; };
int ModelJoinerProxy::rowCount(const QModelIndex &parent) const { int count = 0; //1 if (!parent.isValid()) count = m1->rowCount() + m2->rowCount(); //2 else if (parent.internalId() == -1) { // m1 , // if ( parent.row() < m1->rowCount() ) count = m1->rowCount( m1->index(parent.row(),0) ); // // else if ( parent.row() > (m1->rowCount()-1) && parent.row() < (m1->rowCount() + m2->rowCount()) ) count = m2->rowCount(m2->index(parent.row()-m1->rowCount(), 0)); } return count; } int ModelJoinerProxy::columnCount(const QModelIndex &parent) const { return 1; }
// QModelIndex ModelJoinerProxy::mapToSource(const QModelIndex & proxy) const { // if ( proxy.row() < m1->rowCount() && !proxy.parent().isValid()) { return m1->index(proxy.row(),0) ; } // if ( proxy.parent().isValid()) { return m1->index(proxy.row(),0, m1->index( proxy.parent().row(),0) ); } // if ( proxy.row() > (m1->rowCount()-1) && proxy.row() < (m1->rowCount() + m2->rowCount()) ) { int offset = (proxy.row() - m1->rowCount()); return m2->index(offset, 0); } return QModelIndex(); } // QModelIndex ModelJoinerProxy::mapFromSource(const QModelIndex &source) const { QModelIndex proxy; if (source.model() == m1) { // if (!source.parent().isValid()) { proxy = index(source.row(), 0); } // else { QModelIndex source_parent = index(source.parent().row() ,0); proxy = index(source.row(), 0, source_parent); } } // if (source.model() == m2) { int offset = m1->rowCount() + source.row(); proxy = index(offset, 0); } return proxy; }
QVariant ModelJoinerProxy::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); return mapToSource(index).data(role); }
void ModelJoinerProxy::setSourceModel1(QAbstractItemModel *sourceModel1) { m1 = sourceModel1; connect(m1, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(source_dataChanged(QModelIndex,QModelIndex))); ........ void ModelJoinerProxy::setSourceModel2(QAbstractItemModel *sourceModel2) { m2 = sourceModel2; connect(m2, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(source_dataChanged(QModelIndex,QModelIndex))); ........
void ModelJoinerProxy::source_dataChanged(QModelIndex tl, QModelIndex br) { QModelIndex p_tl = mapFromSource(tl); QModelIndex p_br = mapFromSource(br); emit dataChanged(p_tl, p_br); }
Source: https://habr.com/ru/post/126995/
All Articles