Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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
C++ 将新项添加到基于QAbstractListModel的模型时,QML视图不会更新_C++_Qt_Qml_Qt Quick_Qabstractitemmodel - Fatal编程技术网

C++ 将新项添加到基于QAbstractListModel的模型时,QML视图不会更新

C++ 将新项添加到基于QAbstractListModel的模型时,QML视图不会更新,c++,qt,qml,qt-quick,qabstractitemmodel,C++,Qt,Qml,Qt Quick,Qabstractitemmodel,我已经了解了如何将从QAbstractListModel派生的模型绑定到QML视图 但是下一件事我累了不起作用。如果将新项添加到模型中,QML视图将不会更新。为什么呢 DataObject.h class DataObject { public: DataObject(const QString &firstName, const QString &lastName): first(firstN

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

但是下一件事我累了不起作用。如果将新项添加到模型中,QML视图将不会更新。为什么呢

DataObject.h

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

        QString first;
        QString last;
};
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;
};
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;

};
SimpleListModel.h

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

        QString first;
        QString last;
};
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;
};
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

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::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");
}
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.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::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");
}
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();
}

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

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();

}

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

您忽略了
qabstractemmodel
的语义。模型必须发出两种信号:

  • 数据更改信号:必须在数据更改后发出。数据更改是现有项的值更改。对模型的其他更改不称为数据更改-此处的术语具有特定含义

  • 结构变化信号:必须在任何结构变化前后发出。结构变更是指添加或删除任何项目。
    beginXxxYyy
    endXxxYyy
    辅助函数发出这些信号


是的,除非您使用TreeView或TableView,它们在QML中被破坏,并且仍然不会做出反应。当然,对于ListView来说,它可能会起作用