如何使用 MV 在 Qt 模型中实现层次结构?

How to implement a hierarchical structure in a Qt model using MV?

我最近开始学习Qt,正在研究模型。

我有以下分层模型。

struct group{
 QList<sample> samples;
QString name;
}

struct sample{
QString name;
}

有群组 - 群组列表。每组有几个样本。这样就完成了层次结构。

样本没有children,组没有parent。

但是这个层次结构确实给我带来了问题,我无法使用 qt mv QAbstractItemModel 实现它来像 TreeView 一样显示它。

在树中,作为根 - 我需要显示组的名称,作为叶 - 特定组的特定选择。

您可以在 QModelIndex::internalPointer

中存储指向 groupsample 对象的指针

适配this example,你得到

class GroupModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    explicit GroupModel(QList<group> groups, QObject *parent = nullptr);

    QVariant data(const QModelIndex &index, int role) const override;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const override;
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &index) const override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

private:

    QList<group> groups;
};

GroupModel::GroupModel(QList<group> groups, QObject *parent)
    : QAbstractItemModel(parent), groups(groups)
{
}

QModelIndex GroupModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    if (!parent.isValid())
        return createIndex(row, column, &groups[row]);
    if (group * g = static_cast<group *>(parent.internalPointer()))
        return createIndex(row, column, &g->samples[row]);
    return QModelIndex();
}

QModelIndex GroupModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    void * p = index.internalPointer();

    for (int i = 0; i < groups.count; ++i) 
    {
        if (p == &groups[i]) return QModelIndex();
        for (auto & s : groups[i]->samples)
        {
            if (p == &s) return createIndex(i, 0, &groups[i]);
        }
    }

    return QModelIndex();
}

int GroupModel::rowCount(const QModelIndex &parent) const
{
    if (parent.column() > 0)
        return 0;
    else if (!parent.isValid())
        return groups.count()
    else if (group * g = static_cast<group *>(parent.internalPointer()))
        return g->samples.count();
}

int GroupModel::columnCount(const QModelIndex &parent) const
{
    return 1;
}

QVariant GroupModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    if (!index.parent().isValid())
        return static_cast<group *>(index.internalPointer())->name;

    return static_cast<sample *>(index.internalPointer())->name;
}

QVariant GroupModel::headerData(int section, Qt::Orientation orientation,
                               int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return "Name";

    return QVariant();
}