C++ 将新项添加到基于QAbstractListModel的模型时,QML视图不会更新
我已经了解了如何将从QAbstractListModel派生的模型绑定到QML视图 但是下一件事我累了不起作用。如果将新项添加到模型中,QML视图将不会更新。为什么呢 DataObject.hC++ 将新项添加到基于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
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