How to update QAbstractItemModel view when a Data is updated
18,308
Don't redefine signals in subclasses.
Remove the following lines (in model.h) and it should work as expected :
signals:
void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
Also this when calling dataChanged()
you have to specify a valid QModelIndex
. This is correct :
// I also tried:
QModelIndex topLeft = createIndex(0,0);
emit dataChanged(topLeft, topLeft);
Author by
Ed Nio
Updated on June 25, 2022Comments
-
Ed Nio about 2 years
I use the
Qt example for QAbstractItemModel
and I try to update anItem
to a givenindex
.I tried to use
emit DataChanged
but it doesn't work, the view is not updated.Here is an example:
What I want: When you click on the button, it will update Data at index 0, the
type
of the animal will be changed, it will become a Lion.#include <QAbstractListModel> #include <QStringList> #include <qqmlcontext.h> //![0] class Animal { public: Animal(const QString &type, const QString &size); //![0] QString type() const; QString size() const; void setType(QString q) { m_type = q; } private: QString m_type; QString m_size; //![1] }; class AnimalModel : public QAbstractListModel { Q_OBJECT public: Q_INVOKABLE void test() ; void setName(const QString &name); enum AnimalRoles { TypeRole = Qt::UserRole + 1, SizeRole }; AnimalModel(QObject *parent = 0); //![1] //! //! void setContext(QQmlContext *ctx) { m_ctx = ctx; } void addAnimal(const Animal &animal); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; QHash<int, QByteArray> roleNames() const; protected: private: QList<Animal> m_animals; QQmlContext* m_ctx; signals: void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight); //![2] }; //![2]
model.h
#include "model.h" #include "qDebug" Animal::Animal(const QString &type, const QString &size) : m_type(type), m_size(size) { } QString Animal::type() const { return m_type; } QString Animal::size() const { return m_size; } AnimalModel::AnimalModel(QObject *parent) : QAbstractListModel(parent) { } void AnimalModel::addAnimal(const Animal &animal) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_animals << animal; endInsertRows(); } void AnimalModel::test() { m_animals[0].setType("Lion"); emit dataChanged(QModelIndex(),QModelIndex()); //I also tried: QModelIndex topLeft = createIndex(0,0); emit dataChanged(topLeft, topLeft); } int AnimalModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent); return m_animals.count(); } QVariant AnimalModel::data(const QModelIndex & index, int role) const { if (index.row() < 0 || index.row() >= m_animals.count()) return QVariant(); const Animal &animal = m_animals[index.row()]; if (role == TypeRole) return animal.type(); else if (role == SizeRole) return animal.size(); return QVariant(); } //![0] QHash<int, QByteArray> AnimalModel::roleNames() const { QHash<int, QByteArray> roles; roles[TypeRole] = "type"; roles[SizeRole] = "size"; return roles; } //![0]
model.cpp
#include "model.h" #include <QGuiApplication> #include <qqmlengine.h> #include <qqmlcontext.h> #include <qqml.h> #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> //![0] int main(int argc, char ** argv) { QGuiApplication app(argc, argv); AnimalModel model; model.addAnimal(Animal("Wolf", "Medium")); model.addAnimal(Animal("Polar bear", "Large")); model.addAnimal(Animal("Quoll", "Small")); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); QQmlContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", &model); //![0] view.setSource(QUrl("qrc:view.qml")); view.show(); return app.exec(); }
main.cpp
import QtQuick 2.0 import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.2 import QtQml.Models 2.1 import QtQuick.Controls.Styles 1.2 //![0] ListView { width: 200; height: 250 model: myModel delegate: Text { text: "Animal: " + type + ", " + size } MouseArea { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { } } Button { anchors.bottom: parent.bottom width:50; height:50 text:"click" onClicked: { myModel.test() } } } //![0]
View.qml
Do you have any idea why it doesn't work ? Thanks a lot !
-
derM about 7 yearsOr
emit QAbstractListModel::dataChanged(index(0), index(0));
-
Andrew about 3 yearsbeginResetModel(); endResetModel(); can help you