Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

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

I recently started learning Qt and am studying models.

I have the following hierarchical model.

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

struct sample{
QString name;
}

There are groups - a list of groups. Each group has several samples. This completes the hierarchy.

The sample has no children, and the group has no parent.

But this hierarchy has really caused me problems and I cannot implement it using qt mv QAbstractItemModel to display it like TreeView.

In the tree, as a root - I need to display the name of the group, and as a leaf - a specific selection of a particular group.

question from:https://stackoverflow.com/questions/66061340/how-to-implement-a-hierarchical-structure-in-a-qt-model-using-mv

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can store pointers to your group and sample objects in the QModelIndex::internalPointer

Adapting this example, you get

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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...