将新项目添加到基于QAbstractListModel的模型时,QML视图不会更新 [英] QML view wont update when adding a new item to a QAbstractListModel based model

查看:135
本文介绍了将新项目添加到基于QAbstractListModel的模型时,QML视图不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经弄清楚了如何将从QAbstractListModel派生的模型绑定到QML视图.

I've figured out how to bind a model derived from QAbstractListModel to a QML view.

但是接下来我累的那件事是行不通的.如果将新项目添加到模型,则QML视图将不会更新.为什么会这样?

But the next thing I tired does not work. If a new Item is added to the model the QML view will not update. Why is that?

DataObject.h

class DataObject {
    public:
        DataObject(const QString &firstName,
                   const QString &lastName):
            first(firstName),
            last(lastName) {}

        QString first;
        QString last;
};

SimpleListModel.h

class SimpleListModel : public QAbstractListModel
{
    Q_OBJECT

    enum /*class*/ Roles {
        FIRST_NAME = Qt::UserRole,
        LAST_NAME
    };

    public:
        SimpleListModel(QObject *parent=0);
        QVariant data(const QModelIndex &index, int role) const;
        Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const;
        QHash<int, QByteArray> roleNames() const;
        void addName(QString firstName, QString lastName);

    private:
        Q_DISABLE_COPY(SimpleListModel);
        QList<DataObject*> m_items;
};

SimpleListModel.cpp

SimpleListModel::SimpleListModel(QObject *parent) :
    QAbstractListModel(parent)
{
    DataObject *first = new DataObject(QString("Firstname01"), QString("Lastname01"));
    DataObject *second = new DataObject(QString("Firstname02"), QString("Lastname02"));
    DataObject *third = new DataObject(QString("Firstname03"), QString("Lastname03"));

    m_items.append(first);
    m_items.append(second);
    m_items.append(third);
}

QHash<int, QByteArray> SimpleListModel::roleNames() const
{
    QHash<int, QByteArray> roles;

    roles[/*Roles::*/FIRST_NAME] = "firstName";
    roles[/*Roles::*/LAST_NAME] = "lastName";

    return roles;
}

void SimpleListModel::addName(QString firstName, QString lastName)
{
    DataObject *dataObject = new DataObject(firstName, lastName);

    m_items.append(dataObject);

    emit dataChanged(this->index(m_items.size()), this->index(m_items.size()));
}

int SimpleListModel::rowCount(const QModelIndex &) const
{
    return m_items.size();
}

QVariant SimpleListModel::data(const QModelIndex &index, int role) const
{
    //--- Return Null variant if index is invalid
    if(!index.isValid())
        return QVariant();

    //--- Check bounds
    if(index.row() > (m_items.size() - 1))
        return QVariant();

    DataObject *dobj = m_items.at(index.row());

    switch (role)
    {
        case /*Roles::*/FIRST_NAME:
            return QVariant::fromValue(dobj->first);

        case /*Roles::*/LAST_NAME:
            return QVariant::fromValue(dobj->last);

        default:
            return QVariant();
    }
}

AppCore.h

class AppCore : public QObject
{
    Q_OBJECT
    Q_PROPERTY(SimpleListModel *simpleListModel READ simpleListModel CONSTANT)

    public:
        explicit AppCore(QObject *parent = 0);
        SimpleListModel *simpleListModel() const;

    public slots:
        void addName();

    private:
        SimpleListModel *m_SimpleListModel;

};

AppCore.cpp

AppCore::AppCore(QObject *parent) :
    QObject(parent)
{
    m_SimpleListModel = new SimpleListModel(this);
}

SimpleListModel *AppCore::simpleListModel() const
{
    return m_SimpleListModel;
}

void AppCore::addName()
{
    m_SimpleListModel->addName("FirstnameNEW", "LastnameNEW");
}

main.cpp

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    QQuickView *view = new QQuickView();
    AppCore *appCore = new AppCore();

    qRegisterMetaType<SimpleListModel *>("SimpleListModel");

    view->engine()->rootContext()->setContextProperty("appCore", appCore);
    view->setSource(QUrl::fromLocalFile("main.qml"));
    view->show();

    return a.exec();
}

main.qml

// ...
ListView {
    id: myListView
    anchors.fill: parent
    delegate: myDelegate
    model: appCore.simpleListModel
}

MouseArea {
    anchors.fill: parent
    onClicked: {
        appCore.addName()
        console.log('rowCount: ' + appCore.simpleListModel.rowCount())
    }
}
//...

推荐答案

您应该调用beginInsertRowsendInsertRows而不是发出信号

you should call beginInsertRows and endInsertRows instead of emitting the signal

void SimpleListModel::addName(QString firstName, QString lastName)
{
    DataObject *dataObject = new DataObject(firstName, lastName);

    // tell QT what you will be doing
    beginInsertRows(ModelIndex(),m_items.size(),m_items.size());

    // do it
    m_items.append(dataObject);

    // tell QT you are done
    endInsertRows();

}

这2个函数会发出所有需要的信号

these 2 functions emit all needed signals

这篇关于将新项目添加到基于QAbstractListModel的模型时,QML视图不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆