首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从QAbstractListModel中删除行

从QAbstractListModel中删除行
EN

Stack Overflow用户
提问于 2013-10-10 20:57:10
回答 1查看 13.3K关注 0票数 6

我有一个自定义模型,它从QAbstractListModel派生,这是公开给QML。我需要支持添加新项目和删除现有项目的操作。虽然插入操作没有任何问题,但删除操作会导致应用程序在调用endRemoveRows()函数时崩溃。

代码语言:javascript
复制
    void GPageModel::addNewPage()
    {
        if(m_pageList.count()<9)
        {
            beginInsertRows(QModelIndex(),rowCount(),rowCount());
            GPage * page = new GPage();
            QQmlEngine::setObjectOwnership(page,QQmlEngine::CppOwnership);
            page->setParent(this);
            page->setNumber(m_pageList.count());
            page->setName("Page " + QString::number(m_pageList.count()+1));
            m_pageList.append(page);
            endInsertRows();
        }
    }

    void GPageModel::removePage(const int index)
    {
        if(index>=0 && index<m_pageList.count())
        {        
            beginRemoveRows(QModelIndex(),index,index);
            qDebug()<<QString("beginRemoveRows(QModelIndex(),%1,%1)").arg(index);
            GPage * page = m_pageList.at(index);        
            m_pageList.removeAt(index);
            delete page;
            endRemoveRows();
        }
    }

类GPage派生自QObject。在尝试调用endRemoveRows()时,我试图找出是什么导致应用程序崩溃。当endRemoveRows()为called.How时,我得到"ASSERT failure in QList::at:"index of of range“,我要从QAbstracListModel中删除行吗?还有别的办法吗?

我在Windows 7 64位计算机上使用Qt 5.1.0。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-11 01:26:55

下面的代码对我来说很好用。你的问题可能出在别的地方。这是针对Qt 5的,因为使用了Qt Quick Controls。

有两个视图访问同一个模型,这在视觉上确认了模型发出了适当的信号来通知视图更改。页面的添加和删除是通过通过Q_INVOKABLE导出的标准insertRowsremoveRows方法完成的。到目前为止,这个模型上不需要任何自定义方法。对于QML和QAbstractItemModel之间的接口,Q_INVOKABLE是一些缺失功能的变通方法。

main.cpp

代码语言:javascript
复制
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QAbstractListModel>
#include <QQmlContext>
#include <QtQml>

class GPage : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString name NOTIFY nameChanged MEMBER m_name)
    Q_PROPERTY(int number NOTIFY numberChanged MEMBER m_number)
    QString m_name;
    int m_number;
public:
    GPage(QObject * parent = 0) : QObject(parent), m_number(0) {}
    GPage(QString name, int number, QObject * parent = 0) :
        QObject(parent), m_name(name), m_number(number) {}
    Q_SIGNAL void nameChanged(const QString &);
    Q_SIGNAL void numberChanged(int);
};

class PageModel : public QAbstractListModel {
    Q_OBJECT
    QList<GPage*> m_pageList;
public:
    PageModel(QObject * parent = 0) : QAbstractListModel(parent) {}
    ~PageModel() { qDeleteAll(m_pageList); }
    int rowCount(const QModelIndex &) const Q_DECL_OVERRIDE {
        return m_pageList.count();
    }
    QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE {
        if (role == Qt::DisplayRole || role == Qt::EditRole) {
            return QVariant::fromValue<QObject*>(m_pageList.at(index.row()));
        }
        return QVariant();
    }
    bool setData(const QModelIndex &index, const QVariant &value, int role) Q_DECL_OVERRIDE {
        Q_UNUSED(role);
        GPage* page = value.value<GPage*>();
        if (!page) return false;
        if (page == m_pageList.at(index.row())) return true;
        delete m_pageList.at(index.row());
        m_pageList[index.row()] = page;
        QVector<int> roles;
        roles << role;
        emit dataChanged(index, index, roles);
        return true;
    }
    Q_INVOKABLE bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE {
        Q_UNUSED(parent);
        beginInsertRows(QModelIndex(), row, row + count - 1);
        for (int i = row; i < row + count; ++ i) {
            QString const name = QString("Page %1").arg(i + 1);
            GPage * page = new GPage(name, i + 1, this);
            m_pageList.insert(i, page);
            QQmlEngine::setObjectOwnership(page, QQmlEngine::CppOwnership);
        }
        endInsertRows();
        return true;
    }
    Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE {
        Q_UNUSED(parent);
        beginRemoveRows(QModelIndex(), row, row + count - 1);
        while (count--) delete m_pageList.takeAt(row);
        endRemoveRows();
        return true;
    }
};

int main(int argc, char *argv[])
{
    PageModel model1;
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    model1.insertRows(0, 1);
    engine.rootContext()->setContextProperty("model1", &model1);
    qmlRegisterType<GPage>();
    engine.load(QUrl("qrc:/main.qml"));
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    window->show();
    return app.exec();
}

#include "main.moc"

main.qml

代码语言:javascript
复制
import QtQuick 2.0
import QtQml.Models 2.1
import QtQuick.Controls 1.0

ApplicationWindow {
    width: 300; height: 300
    Row {
        width: parent.width
        anchors.top: parent.top
        anchors.bottom: column.top
        Component {
            id: commonDelegate
            Rectangle {
                width: view.width
                implicitHeight: editor.implicitHeight + 10
                color: "transparent"
                border.color: "red"
                border.width: 2
                radius: 5
                TextInput {
                    id: editor
                    anchors.margins: 1.5 * parent.border.width
                    anchors.fill: parent
                    text: edit.name // "edit" role of the model, to break the binding loop
                    onTextChanged: {
                        display.name = text;
                        model.display = display
                    }
                }
            }
        }
        ListView {
            id: view
            width: parent.width / 2
            height: parent.height
            model: DelegateModel {
                id: delegateModel1
                model: model1
                delegate: commonDelegate
            }
            spacing: 2
        }
        ListView {
            width: parent.width / 2
            height: parent.height
            model: DelegateModel {
                model: model1
                delegate: commonDelegate
            }
            spacing: 2
        }
    }
    Column {
        id: column;
        anchors.bottom: parent.bottom
        Row {
            Button {
                text: "Add Page";
                onClicked: model1.insertRows(delegateModel1.count, 1)
            }
            Button {
                text: "Remove Page";
                onClicked: model1.removeRows(pageNo.value - 1, 1)
            }
            SpinBox {
                id: pageNo
                minimumValue: 1
                maximumValue: delegateModel1.count;
            }
        }
    }
}

main.qrc

代码语言:javascript
复制
<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19296383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档