如何通知 ListView DataModel 已更改
Posted
技术标签:
【中文标题】如何通知 ListView DataModel 已更改【英文标题】:How to notify ListView that DataModel has changed 【发布时间】:2016-05-22 01:02:37 【问题描述】:我创建了一个ListView
,我想将它与自定义DataModel
一起使用。但是,我有一个问题:在创建视图的那一刻,我没有将数据加载到模型中。模型数据是在创建视图后设置的,当我将数据设置到模型上时,视图不会更新,也不会再次读取模型数据。这是我的ListView
:
ListViewCountainer.qml
Container
// countryModelData is set after ListViewCountainer gets created
// when countryModelData gets set, the model is populated with data
property variant countryModelData
leftPadding: 20.0
rightPadding: 20.0
topPadding: 20.0
bottomPadding: 20.0
CountryDetailsListView
id: countryDetailsListView
dataModel: CountryDataModel
countryData: countryModelData
这是我的模型:
countrydatamodel.h
#ifndef COUNTRYDATAMODEL_H_
#define COUNTRYDATAMODEL_H_
#include <QtCore/QAbstractListModel>
#include <QtCore/QList>
#include <QObject>
#include <QtCore/QVariant>
#include <bb/cascades/DataModel>
#include <bb/data/JsonDataAccess>
class CountryDataModel : public bb::cascades::DataModel
Q_OBJECT
Q_PROPERTY(QVariant countryData READ getCountryData WRITE setCountryData)
public:
CountryDataModel(QObject* parent = 0);
virtual ~CountryDataModel();
Q_INVOKABLE int childCount(const QVariantList& indexPath);
Q_INVOKABLE QVariant data(const QVariantList& indexPath);
Q_INVOKABLE bool hasChildren(const QVariantList& indexPath);
Q_INVOKABLE QString itemType(const QVariantList& indexPath);
Q_INVOKABLE void removeItem(const QVariantList& indexPath);
Q_INVOKABLE QVariant getCountryData();
Q_INVOKABLE void setCountryData(QVariant data);
private:
QVariantList m_elements;
;
#endif /* COUNTRYDATAMODEL_H_ */
countrydatamodel.cpp
#include <src/countrydatamodel.h>
#include <QtCore/QtAlgorithms>
#include <QtCore/QDebug>
#include <bb/cascades/DataModel>
#include <bb/data/JsonDataAccess>
CountryDataModel::CountryDataModel(QObject* parent) : bb::cascades::DataModel(parent)
CountryDataModel::~CountryDataModel()
bool CountryDataModel::hasChildren(const QVariantList &indexPath)
qDebug() << "==== CountryDataModel::hasChildren" << indexPath;
if ((indexPath.size() == 0))
return true;
else
return false;
int CountryDataModel::childCount(const QVariantList &indexPath)
qDebug() << "==== CountryDataModel::childCount" << indexPath;
if (indexPath.size() == 0)
qDebug() << "CountryDataModel::childCount" << m_elements.size();
return m_elements.size();
qDebug() << "==== CountryDataModel::childCount" << 0;
return 0;
QVariant CountryDataModel::data(const QVariantList &indexPath)
qDebug() << "==== CountryDataModel::data" << indexPath;
if (indexPath.size() == 1)
return m_elements.at(indexPath.at(0).toInt());
QVariant v;
return v;
QString CountryDataModel::itemType(const QVariantList &indexPath)
Q_UNUSED(indexPath);
return "";
void CountryDataModel::removeItem(const QVariantList& indexPath)
if(indexPath.size() == 1)
m_elements.removeAt(indexPath.at(0).toInt());
emit itemRemoved(indexPath);
QVariant CountryDataModel::getCountryData()
return QVariant(m_elements);
void CountryDataModel::setCountryData(QVariant data)
m_elements = data.toList();
qDebug() << "================== CountryDataModel: " << m_elements;
例如,我在childCount
函数中放置了一些调试消息,它只被调用一次,这意味着ListView
在创建模型时只向模型询问数据一次。
是否可以强制ListView
在模型填充数据后再次从模型中读取数据?或者我怎样才能使这种方法工作并在视图中加载数据?
谢谢!
【问题讨论】:
【参考方案1】:为了更新模型,setCountryData
成员函数需要像这样更新:
void CountryDataModel::setCountryData(QVariant data)
m_elements = data.toList();
emit itemsChanged(bb::cascades::DataModelChangeType::AddRemove, QSharedPointer< bb::cascades::DataModel::IndexMapper >(0));
FML...
【讨论】:
【参考方案2】:您需要为要在后端更新的属性声明一个信号。
Q_PROPERTY(QVariant countryData READ getCountryData WRITE setCountryData NOTIFY contryDataChanged)
也添加它的声明。
那你说——
emit contryDataChanged();
只要你觉得列表应该重新阅读内容。 (通常是 setter 方法)。
【讨论】:
将 countryData 设为属性并发出通知信号与视图没有任何关系。以上是关于如何通知 ListView DataModel 已更改的主要内容,如果未能解决你的问题,请参考以下文章