Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 从QAbstractListModel中删除行_Qt_Qml_Qtquick2_Qabstractitemmodel_Qabstractlistmodel - Fatal编程技术网

Qt 从QAbstractListModel中删除行

Qt 从QAbstractListModel中删除行,qt,qml,qtquick2,qabstractitemmodel,qabstractlistmodel,Qt,Qml,Qtquick2,Qabstractitemmodel,Qabstractlistmodel,我有一个自定义模型,它是从QAbstractListModel派生的,QAbstractListModel暴露于QML。我需要支持添加新项目和删除现有项目的操作。虽然插入操作可以正常工作,但删除操作会导致应用程序在调用endRemoveRows()函数时崩溃 void GPageModel::addNewPage() { if(m_pageList.count()<9) { beginInsertRows(QModel

我有一个自定义模型,它是从QAbstractListModel派生的,QAbstractListModel暴露于QML。我需要支持添加新项目和删除现有项目的操作。虽然插入操作可以正常工作,但删除操作会导致应用程序在调用endRemoveRows()函数时崩溃

    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();
        }
    }
void GPageModel::addNewPage()
{
if(m_pageList.count()setParent(this);
页面->设置编号(m_pageList.count());
page->setName(“page”+QString::number(m_pageList.count()+1));
m_pageList.append(第页);
endInsertRows();
}
}
void GPageModel::removePage(const int index)
{

如果(index>=0&&index,下面的代码对我来说很好。您的问题可能在别处。这是因为使用了Qt快速控件而导致的Qt 5

有两个视图访问同一个模型,这从视觉上确认模型发出适当的信号来通知视图更改。页面的添加和删除是通过标准的
insertRows
removows
方法完成的,通过
Q_INVOKABLE
导出到目前为止,他的模型。
Q_INVOKABLE
是解决QML和
qabstractemmodel
之间接口功能缺失的一种方法

main.cpp

#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.qrc

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>

main.qml

doe gpage继承自QObject?如果是这样,请使用
page.deleteLater();
而不是直接删除Sorry…我应该提供更多信息。我已经编辑了我的问题。我尝试使用page->deleteLater()。但应用程序仍然崩溃。感谢您尝试。您对问题可能在其他地方的怀疑让我想到了其他问题,您是对的。我的子类中有一个方法,它是一个Q_可调用函数,在给定索引处将GPage*实例作为QObject*返回。我在委托中使用此函数绑定属性。例如:
text:pageModel.at(index).name
QObject*GPageModel::at(int index){return m_pageList.at(index);}
每当调用endRemoveRows时,下一个要调用的函数就是上面的函数,其索引为-1,这导致了crash@Wonderkid:OTOH,为什么要在()上设置自定义
数据()时的方法
工作得很好?我的意思是,如果你只是随机实现自己的功能,为什么还要使用模型呢?即使我的示例也不完全符合犹太标准,因为我不应该添加
size
属性,我只是太懒了,不能正确地做;我会解决这个问题。在
QV上作为
QObject*
传递
GPage*
也很好变量
,您可以正常使用
GPage
的属性,尽管将其从
数据()中传递出去
方法。@Wonderkid:看看我是如何在委托中使用
GPage
的属性的。检索的神奇语法是
role.property
。对于设置,您可以通过
role
model.role
-调用
setData
,直接访问项目的用户属性
role.property
,但它不会调用
setData
,只是修改
data
之前返回的
GPage
的实例。要设置模型,您需要:1.修改对象并使用
role
/
model.role
或2.将属性映射到角色,很容易完成使用
roleNames
机制。@Wonderkid:这一切都可以通过股票模型来完成,其中一些方法是
Q\u可调用的
,再加上
DelegateModel
(不是
VisualModel
)。无需自定义方法:)谢谢您的解决方案。+1详细解释。
<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>