Dynamic Upadate of data to a ListModel
-
I have triggered it exactly when my data is being changed.
My model:
class DataList{ public: DataList(const QString &name, const QString &value, const QString &category); QString name() const; QString value() const; QString category() const; private: QString m_name; QString m_value; QString m_category; }; class DataModel : public QAbstractListModel { Q_OBJECT public: enum Roles { NameRole = Qt::UserRole + 1, ValueRole, CategoryRole }; DataModel(QAbstractItemModel *parent = 0); virtual ~DataModel() {} void addData(const DataList &datalist); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role=NameRole) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<DataList> m_datalist; public slots: void onInitialPolygonAreaChanged(qreal); };
-
@saitej said in Dynamic Upadate of data to a ListModel:
I have triggered it exactly when my data is being changed.
but who reads the
ValueRole
?! The view doesn't, it uses the `Qt::DisplayRole' by default.Also posting the header file of your model implementation is almost as good as providing nothing ;)
-
DataList::DataList(const QString &name, const QString &value, const QString &category){ m_name = name; m_value = value; m_category = category; } QString DataList::name() const{ return m_name; } QString DataList::value() const{ return m_value; } QString DataList::category() const{ return m_category; } DataModel::DataModel(QAbstractItemModel *parent) : QAbstractListModel(parent) { } void DataModel::addData(const DataList &datalist){ beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_datalist << datalist; } int DataModel::rowCount(const QModelIndex &parent) const{ Q_UNUSED(parent); return m_datalist.count(); } QVariant DataModel::data(const QModelIndex &index, int role) const{ if (index.row() < 0 || index.row() >= m_datalist.count()) return QVariant(); const DataList &datalist = m_datalist[index.row()]; if(role ==NameRole ) return datalist.name(); else if(role == ValueRole) return datalist.value(); else if(role == CategoryRole) return datalist.category(); return QVariant(); } QHash<int, QByteArray> DataModel::roleNames() const { QHash<int, QByteArray> roles; roles[NameRole] = "name"; roles[ValueRole] = "value"; roles[CategoryRole] = "category"; return roles; } void DataModel::onInitialPolygonAreaChanged(qreal ){ //0 is the index of iPA qDebug() << "IPA from model" ; QVector<int> roleVector(ValueRole); emit dataChanged(index(0),index(0),roleVector); }
-
- DataModel constructor: not an issue, but i guess it's not necessary to require a QAbstractItemModel type as parent. I would change it to QObject
- you are not calling endInserteRows() in DataModel::addData() after you've appended the data.
- I ask one last time, since you are also not returning a DisplayRole value. How is your view using the ValueRole
I don't see where the call to onInitialPolygonAreaChanged() comes from, and where the data update before this call happens.
If you call addData() before triggering the onInitialPolygonAreaChanged() slot, all you need is to add the endInsertRows() call. If thats the case you also DO NOT need to make sure dataChanged() is triggered, because as i also already said, this is only necessary for EXISTING data changes. The updating on inserts is already handled by the beginInsertRows()/endInsertRows() calls. -
I have initialized the model in the main window.h :
DataModel model;
In the mainwindow.cpp file
model.addData(DataList(QString("Initial Polygon Area"),QString::number(uav1.initialPolygonArea()) + " sq.km",QString("Area"))); connect(&uav1,SIGNAL(initialPolygonAreaChanged(qreal)),&model,SLOT(onInitialPolygonAreaChanged(qreal)));
This is how I am calling onInitialPolygonAreaChanged slot.
-
@raven-worx said in Dynamic Upadate of data to a ListModel:
I ask one last time, since you are also not returning a DisplayRole value. How is your view using the ValueRole
Where should I return DisplayRole and why ?
This is how I am using in the view:
qml file:
ListView { id: view anchors.top: parent.top anchors.bottom: parent.bottom width: parent.width model: UAVModel delegate: Text { text: name + " " + value; font.pixelSize: 18 ; color: "white"} section.property: "category" section.criteria: ViewSection.FullString section.delegate: sectionHeading }
-
@saitej said in Dynamic Upadate of data to a ListModel:
Where should I return DisplayRole and why ?
Nevermind, it took me a while realizing that we are here in the QML sub-forum. My bad.
-
So in QML, is there a different way to update the model or the same datachanged() signal should work?
-
-
Ya my code is completely based on this. They have also mentioned :
QML views are automatically updated when the model changes. Remember the model must follow the standard rules for model changes and notify the view when the model has changed by using QAbstractItemModel::dataChanged(), QAbstractItemModel::beginInsertRows(), and so on. See the Model subclassing reference for more information.
So I thought the model should be updated with datachanged() but it doesn't seem to. Any ideas to debug
-
@saitej use dataChanged() signal as was mentioned before.
check if data() called after you have emitted the signal
also I'm a bit skeptical about default role in QVariant data(const QModelIndex & index, int role=NameRole)
anyway, check if data() gets called -
@saitej said in Dynamic Upadate of data to a ListModel:
So I thought the model should be updated with datachanged() but it doesn't seem to. Any ideas to debug
post your model code and i tell you whats wrong
-