Skip to content

Instantly share code, notes, and snippets.

@Matthew-McRaven
Created March 7, 2024 17:43
Show Gist options
  • Save Matthew-McRaven/ec7cd0f8b5ba46b2246ae78896898b7b to your computer and use it in GitHub Desktop.
Save Matthew-McRaven/ec7cd0f8b5ba46b2246ae78896898b7b to your computer and use it in GitHub Desktop.
Proxy model which limits the "top level" to be the child element of some other model. Uses Qt 6.6.0.
#include "descendantproxymodel.hpp"
DescendantProxyModel::DescendantProxyModel(QObject *parent)
: QAbstractProxyModel(parent)
{}
void DescendantProxyModel::setSourceRootIndex(const QModelIndex index)
{
beginResetModel();
sourceRootIndex = index;
endResetModel();
}
QModelIndex DescendantProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
if (!proxyIndex.isValid())
return QModelIndex();
else if (!sourceRootIndex.isValid())
return QModelIndex();
return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), proxyIndex.parent());
}
QModelIndex DescendantProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
if (!sourceIndex.isValid())
return {};
return sourceModel()->index(sourceIndex.row(), sourceIndex.column(), sourceIndex.parent());
}
QModelIndex DescendantProxyModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
QModelIndex parentIndex = parent.isValid() ? mapToSource(parent) : sourceRootIndex;
QModelIndex sourceIndex = sourceModel()->index(row, column, parentIndex);
return mapFromSource(sourceIndex);
}
QModelIndex DescendantProxyModel::parent(const QModelIndex &child) const
{
if (!child.isValid())
return QModelIndex();
QModelIndex sourceChild = mapToSource(child);
QModelIndex sourceParent = sourceChild.parent();
return mapFromSource(sourceParent);
}
int DescendantProxyModel::rowCount(const QModelIndex &parent) const
{
QModelIndex parentIndex = parent.isValid() ? mapToSource(parent) : sourceRootIndex;
return parentIndex.isValid() ? sourceModel()->rowCount(parentIndex) : 0;
}
int DescendantProxyModel::columnCount(const QModelIndex &parent) const
{
QModelIndex parentIndex = parent.isValid() ? mapToSource(parent) : sourceRootIndex;
return parentIndex.isValid() ? sourceModel()->columnCount(parentIndex) : 0;
}
QVariant DescendantProxyModel::data(const QModelIndex &proxyIndex, int role) const
{
if (!proxyIndex.isValid())
return QVariant();
QModelIndex sourceIndex = mapToSource(proxyIndex);
return sourceModel()->data(sourceIndex, role);
}
#pragma once
#include <QAbstractProxyModel>
#include <QModelIndex>
class DescendantProxyModel : public QAbstractProxyModel
{
Q_OBJECT
public:
explicit DescendantProxyModel(QObject *parent = nullptr);
// Set the root index from the source model
Q_INVOKABLE void setSourceRootIndex(const QModelIndex sourceRootIndex);
// Required method overrides
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override;
private:
QModelIndex sourceRootIndex; // The root index in the source model
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment