如何使用QAbstractItemModel映射多级对象模型

时间:2019-03-13 14:36:38

标签: c++ qt model-view-controller

我开始在Qt中学习MVC模式。

我具有简单的数据结构,如下所示:

class Stage
{
public:
    QString name;
    int number;
};

class Doc
{
public:
    Doc();
    ~Doc();
    QString name;
    int number;
    QList<Stage *> *stages;
};

我想在TreeView中查看此结构。为此,我创建模型类:

class Model: public QAbstractItemModel
{
    Q_OBJECT

public:
    Model(QObject *parent);
    ~Model();

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    QModelIndex index(int row, int column, const QModelIndex &parent) const;
    QModelIndex parent(const QModelIndex &index) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const;
private:
    QList<Doc*> *docs;

如果我只有一层数据(没有阶段的文档),那么一切都很好,但是我不明白如何向模型(阶段)添加第二棵树?

代码示例(一级)

Model::Model(QObject *parent) : QAbstractItemModel(parent)
{
    docs = new QList<Doc*>();
    for (int i = 0; i < 3; ++i) {
        Doc *d = new Doc();
        d->name = "name_" + QString::number(i);
        d->number = i;
        docs->append(d);
    }
}

Model::~Model()
{
    delete docs;
}

QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
    if (!parent.isValid()) {
        Doc *d = docs->at(row);
        return createIndex(row, column, d);
    } 
    return QModelIndex();
}

QModelIndex Model::parent(const QModelIndex &index) const
{
    return QModelIndex();
}

int Model::rowCount(const QModelIndex &parent) const
{
    int cnt = 0;
    if (!parent.isValid()) {
        cnt = docs->size();
    } 
    return cnt;
}

int Model::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 3;
}

Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return nullptr;
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
        return QVariant();

    if (orientation == Qt::Horizontal) {
        switch (section) {
        case 0:
            return tr("Number");
        case 1:
            return tr("Code");
        case 2:
            return tr("Stages count");
        default:
            return QVariant();
        }
    }
    return QVariant();
}

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

    if (role != Qt::DisplayRole)
        return QVariant();
    {
        Doc *d = static_cast<Doc*>(index.internalPointer());

        switch (index.column()) {
        case 0:
            return d->name;
        case 1:
            return d->number;
        case 2:
            return d->stages->size();
        default:
            break;
        }
    }
    return QVariant();
}

我认为它会像这样:

Model::Model(QObject *parent) : QAbstractItemModel(parent)
{
    docs = new QList<Doc*>();
    for (int i = 0; i < 3; ++i) {
        Doc *d = new Doc();
        d->name = "name_" + QString::number(i);
        d->number = i;
        for (int j = 5; j < 9; ++j) {
            Stage *s = new Stage();
            s->name = "name_" + QString::number(j);
            s->number = j;
            d->stages->append(s);
        }
        docs->append(d);
    }
}


QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
    if (!parent.isValid()) {
        Doc *d = docs->at(row);
        return createIndex(row, column, d);
    } else {
        Stage *s = static_cast<Doc*>(parent.internalPointer())->stages->at(row);
        return createIndex(row, column, s);
    }
    return QModelIndex();
}

QModelIndex Model::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();
    else if (index.parent().isValid())
        return createIndex(index.parent().row(), 0, index.internalPointer());
    return QModelIndex();
}

int Model::rowCount(const QModelIndex &parent) const
{
    int cnt = 0;
    if (!parent.isValid()) {
        cnt = docs->size();
    } else {
        cnt = static_cast<Doc*>(parent.parent().internalPointer())->stages->size();
    }
    return cnt;
}

但是它的代码错误...

0 个答案:

没有答案