Salut,
J’essaie de faire un proxymodel Qt qui prend un model sous forme d’arbre et en expose qu’une de ses branches
O
|-A
| |-AA
| |-X
|
|-B
|-BB
|-Y
deviens
O
|-AA
|-X
si je construit mon Proxy sur le nom "AA"
Mais je ne m’en sort pas avec le système de model Qt, je dois passer à côté de quelque chose, avoir compris la doc de travers.
J’ai implémenté un QAbstractProxyModel pour arriver à mes fins. Malheureusement, lorsque je l’associe à une TreeView, un Q_ASSERT du setModel se déclanche : "The parent of a top level index should be invalid". Pourtant je crois bien avoir associé un QModelIndex invalide en tant que parent de ma nouvelle racine (en le mappant).
Voici le code que j’ai écrit :
branchproxymodel.h
#ifndef BRANCHPROXYMODEL_H
#define BRANCHPROXYMODEL_H
#include <QAbstractProxyModel>
class BranchProxyModel : public QAbstractProxyModel
{
public:
BranchProxyModel(const QString & branchname, QObject* parent = nullptr);
~BranchProxyModel() override;
void setSourceModel(QAbstractItemModel *sourceModel) override;
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
int columnCount(const QModelIndex & parent) const override;
int rowCount(const QModelIndex & parent) const override;
QModelIndex index(int row, int column, const QModelIndex & parent) const override;
QModelIndex parent(const QModelIndex & index) const override;
public slots:
void sourceDataChanged(QModelIndex topLeft, QModelIndex bottomRight);
private:
void extractBranch(const QModelIndex & branchIndex, const QModelIndex &parent= QModelIndex());
QModelIndex findIndexOfBranch(QAbstractItemModel* model, const QModelIndex & parent = QModelIndex()) const;
QString m_branchName;
QModelIndex m_branchRoot;
QMap<QModelIndex, QModelIndex> m_indexMap;
QMap<QModelIndex, QModelIndex> m_parentMap;
};
#endif // BRANCHPROXYMODEL_H
branchproxymodel.cpp
#include "gui/typeexplorer/branchproxymodel.h"
#include <QDebug>
BranchProxyModel::BranchProxyModel(const QString &branchname, QObject *parent):
QAbstractProxyModel(parent),
m_branchName(branchname),
m_branchRoot(),
m_indexMap(),
m_parentMap()
{
}
BranchProxyModel::~BranchProxyModel()
{
}
void BranchProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
QAbstractProxyModel::setSourceModel(sourceModel);
m_branchRoot = findIndexOfBranch(sourceModel);
extractBranch(m_branchRoot);
connect(sourceModel, &QAbstractItemModel::dataChanged, this, &BranchProxyModel::sourceDataChanged);
}
QModelIndex BranchProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
if(m_indexMap.contains(sourceIndex))
return m_indexMap[sourceIndex];
else
return QModelIndex();
}
QModelIndex BranchProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
if(!proxyIndex.isValid())
return QModelIndex();
else if(!proxyIndex.parent().isValid())
return m_branchRoot;
else
{
QModelIndex sourceParent = mapToSource(proxyIndex.parent());
return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), sourceParent);
}
}
int BranchProxyModel::columnCount(const QModelIndex &parent) const
{
return sourceModel()->columnCount(mapToSource(parent));
}
int BranchProxyModel::rowCount(const QModelIndex &parent) const
{
if(!parent.isValid())
return 1;
else
return sourceModel()->rowCount(mapToSource(parent));
}
QModelIndex BranchProxyModel::index(int row, int column, const QModelIndex &parent) const
{
if(!parent.isValid())
return m_indexMap[m_branchRoot];
else
return m_indexMap[mapToSource(parent)].child(row, column);
}
QModelIndex BranchProxyModel::parent(const QModelIndex &index) const
{
return m_parentMap[index];
}
void BranchProxyModel::sourceDataChanged(QModelIndex topLeft, QModelIndex bottomRight)
{
emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight));
}
void BranchProxyModel::extractBranch(const QModelIndex & branchIndex, const QModelIndex &parent)
{
if(!parent.isValid())
{
m_indexMap.clear();
m_parentMap.clear();
}
if(branchIndex.column() == 0)
{
QModelIndex proxyIndex;
if(branchIndex == m_branchRoot)
proxyIndex = createIndex(0, branchIndex.column());
else
proxyIndex = createIndex(branchIndex.row(), branchIndex.column());
m_indexMap.insert(branchIndex, proxyIndex);
m_parentMap.insert(proxyIndex, parent);
for(int i = 0; i < sourceModel()->rowCount(branchIndex); ++i)
{
extractBranch(branchIndex.child(i, 0), proxyIndex);
}
}
}
QModelIndex BranchProxyModel::findIndexOfBranch(QAbstractItemModel *model, const QModelIndex &parent) const
{
for(int i = 0; i < model->rowCount(parent); ++i)
{
QModelIndex index = model->index(i, 0, parent);
if(model->data(index) == m_branchName)
{
return index;
}
}
QModelIndex resultOfChild;
for(int i = 0; i < model->rowCount(parent); ++i)
{
QModelIndex index = model->index(i, 0, parent);
resultOfChild = findIndexOfBranch(model, index);
if(resultOfChild.isValid())
return resultOfChild;
}
return QModelIndex();
}
+0
-0