C++ 从自定义QAbstractItemModel树模型中删除行

C++ 从自定义QAbstractItemModel树模型中删除行,c++,qt,C++,Qt,使用简单的定制qabstractemmodel以及从中删除行时,我面临着奇怪的崩溃 模型 假设以下简单的基于qabstractemmodel的树: #include <QAbstractItemModel> #include <QModelIndex> #include <QStringList> #include <QVariant> #include <QString> #include <QObject> class

使用简单的定制
qabstractemmodel
以及从中删除行时,我面临着奇怪的崩溃

模型 假设以下简单的基于
qabstractemmodel
的树:

#include <QAbstractItemModel>
#include <QModelIndex>
#include <QStringList>
#include <QVariant>
#include <QString>
#include <QObject>

class UnitsModel:
    public QAbstractItemModel {

    Q_OBJECT

    public:
        UnitsModel(QObject *parent):
            QAbstractItemModel(parent) {

            dimensions.append(qMakePair(
                QString("Length"),
                QStringList() << "Meter" << "Kilometer"));

            dimensions.append(qMakePair(
                QString("Weight"),
                QStringList() << "Gram" << "Kilogram" << "Ton"));
        }


        QModelIndex index(int row, int column, const QModelIndex &parent) const {
            if (column >= 1)
                return QModelIndex();

            if (!parent.isValid()) {
                /* Index to dimension */
                if (row < dimensions.count())
                    return createIndex(row, column, static_cast<quintptr>(-1));
            }
            else if (parent.row() < dimensions.count()) {
                /* Index to unit */
                const QStringList &units = dimensions.at(parent.row()).second;
                if (row < units.count())
                    return createIndex(row, column, static_cast<quintptr>(parent.row()));
            }

            return QModelIndex();
        }

        QModelIndex parent(const QModelIndex &child) const {
            if (!child.isValid())
                return QModelIndex();

            const int i = static_cast<qintptr>(child.internalId());
            if (i < 0) {
                /* Child is index to dimension */
                return QModelIndex();
            }
            else {
                /* Child is index to unit */
                if (i < dimensions.count())
                    return createIndex(i, 0, static_cast<quintptr>(-1));
            }

            return QModelIndex();
        }

        int rowCount(const QModelIndex &parent) const {
            if (!parent.isValid())
                return dimensions.count();

            const int i = static_cast<qintptr>(parent.internalId());
            if (i < 0) {
                /* Index to dimension */
                if (parent.row() < dimensions.count()) {
                    const QStringList &units = dimensions.at(parent.row()).second;
                    return units.count();
                }
            }
            else {
                /* Index to unit */
                return 0;
            }

            return 0;
        }

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

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

            const QModelIndex parent = index.parent();
            if (!parent.isValid()) {
                if (index.row() >= dimensions.count())
                    return QVariant();

                /* Index to dimension */
                if (role == Qt::DisplayRole)
                    return dimensions.at(index.row()).first;
            }
            else {
                /* Index to unit */
                const QStringList &units = dimensions.at(parent.row()).second;
                if (index.row() >= units.count())
                    return QVariant();

                if (role == Qt::DisplayRole)
                    return units.at(index.row());
            }

            return QVariant();
        }



        void removeFirstRow() {
            beginRemoveRows(QModelIndex(), 0, 0);
            dimensions.removeAt(0);
            endRemoveRows();
        }


    private:
        QList< QPair<QString, QStringList> > dimensions;
};
更糟糕的是,如果我重新启动并选择kiggle,然后调用
UnitsModel::removeFirstRow()
两次以删除这两个顶级项,则树视图将正确清除(包括上述警告)。然后,当删除仍由
QTreeView
使用的模型时,应用程序在退出时崩溃。回溯可以追溯到一个
QPersistentModelIndex
d-tor,所以我想前面提到的警告是关于一个在删除行时无法调整的持久索引。然后退出应用程序时,此模型索引“d-tor”尝试从已销毁的模型中注销自己

我认为主要问题是警告。模型有什么问题,为什么不能正确调整持久性指数

作为旁注:删除仍在使用中的模型完全可以,因为
QTreeView
连接到其模型的
destromed()
信号,并使用空占位符模型重置自身

QAbstractItemModel::endRemoveRows:  Invalid index ( 0 , 0 ) in model UnitsModel(0xb46c70)