【问题标题】:How to notify ListView that DataModel has changed如何通知 ListView DataModel 已更改
【发布时间】: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 在模型填充数据后再次从模型中读取数据?或者我怎样才能使这种方法工作并在视图中加载数据?

谢谢!

【问题讨论】:

    标签: qml blackberry-10 qtquick2 blackberry-simulator blackberry-cascades


    【解决方案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 设为属性并发出通知信号与视图没有任何关系。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 2011-09-22
      • 2010-11-23
      • 2011-03-09
      • 1970-01-01
      相关资源
      最近更新 更多