Change data on QAbstractItemModel subclass model
-
I want to update data from c++ side. I tried to write setters for Item class, but when I try to use them an error apiers: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
m_item.at(i).setDescription(value); How to change the internal data the right way? -
I want to update data from c++ side. I tried to write setters for Item class, but when I try to use them an error apiers: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
m_item.at(i).setDescription(value); How to change the internal data the right way?@m.kuncevicius Maybe you tried to do something like
void Item::setDescription(QString desc) const
In that case you have to remove 'const' because it's a setter and quite logically modifies the 'this' object and therefore can't be a const member function. Using the keyword const like this is meant for the member functions which don't modify the perceived state of the 'this' object. (See e.g. https://isocpp.org/wiki/faq/const-correctness#const-member-fns .)
-
@m.kuncevicius Maybe you tried to do something like
void Item::setDescription(QString desc) const
In that case you have to remove 'const' because it's a setter and quite logically modifies the 'this' object and therefore can't be a const member function. Using the keyword const like this is meant for the member functions which don't modify the perceived state of the 'this' object. (See e.g. https://isocpp.org/wiki/faq/const-correctness#const-member-fns .)
@Eeli-K Thank you for answer, but setter is not const.
-
@Eeli-K Thank you for answer, but setter is not const.
@m.kuncevicius Then you have to give the code, otherwise it's impossible to say where the problem is. The error message refers to a situation where a method is const but the this object is changed in it.
-
@m.kuncevicius Then you have to give the code, otherwise it's impossible to say where the problem is. The error message refers to a situation where a method is const but the this object is changed in it.
@Eeli-K I just added auto genereted setter. The rest of my code:
Header:
void setName(const QString &value);
.cpp
void Item::setName(const QString &value) { name = value; }
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "item.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; auto context = engine.rootContext(); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); ItemModel itemModel; itemModel.addItem(Item("Name1", "Description1", "12,25", "113548", 1)); itemModel.addItem(Item("Name2", "Description2", "22,25", "213548", 2)); itemModel.addItem(Item("Name3", "Description3", "32,25", "313548", 3)); itemModel.item().at(1).setName("Changed"); context->setContextProperty("itemModel", &itemModel); return app.exec(); }
-
@Eeli-K I just added auto genereted setter. The rest of my code:
Header:
void setName(const QString &value);
.cpp
void Item::setName(const QString &value) { name = value; }
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "item.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; auto context = engine.rootContext(); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); ItemModel itemModel; itemModel.addItem(Item("Name1", "Description1", "12,25", "113548", 1)); itemModel.addItem(Item("Name2", "Description2", "22,25", "213548", 2)); itemModel.addItem(Item("Name3", "Description3", "32,25", "313548", 3)); itemModel.item().at(1).setName("Changed"); context->setContextProperty("itemModel", &itemModel); return app.exec(); }
@m.kuncevicius
Please paste the error message here and tell what code line it refers to.QList<Item> ItemModel::item() const { return m_item; }
returns a copy so you can't change the model's item through that. But even if it would return a reference or a pointer the model wouldn't work properly because it wouldn't send signals when items are changed. Write the modifier API in the model class, hide the item completely inside it. Either write something like ItemModel::setName(int index, QString name) or override setData. In the model's code when the model data is changed you have to emit some signals; see the QAbstractItemModel Subclassing documentation.
-
@m.kuncevicius
Please paste the error message here and tell what code line it refers to.QList<Item> ItemModel::item() const { return m_item; }
returns a copy so you can't change the model's item through that. But even if it would return a reference or a pointer the model wouldn't work properly because it wouldn't send signals when items are changed. Write the modifier API in the model class, hide the item completely inside it. Either write something like ItemModel::setName(int index, QString name) or override setData. In the model's code when the model data is changed you have to emit some signals; see the QAbstractItemModel Subclassing documentation.
@Eeli-K said in Change data on QAbstractItemModel subclass model:
ItemModel::setName(int index, QString name)
I tried this before. But it shows the same error:
item.cpp:94: error: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
m_item.at(index).setName(name);
^void ItemModel::setName(int index, QString name) { m_item.at(index).setName(name); }
-
@Eeli-K said in Change data on QAbstractItemModel subclass model:
ItemModel::setName(int index, QString name)
I tried this before. But it shows the same error:
item.cpp:94: error: passing 'const Item' as 'this' argument discards qualifiers [-fpermissive]
m_item.at(index).setName(name);
^void ItemModel::setName(int index, QString name) { m_item.at(index).setName(name); }
@m.kuncevicius Maybe it's because
const T &QList::at(int i) const
returns a const. Try the [] operator.Then add emit dataChanged to that data modifying method so that the view is automatically updated.
-
on top of using
operator[]
,int ItemModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent); return m_item.count(); }
is infinite recursion. for a list it should be:
int ItemModel::rowCount(const QModelIndex & parent) const { if(parent.isValid()) return 0; return m_item.count(); }
void setItem(const QList<Item> &item);
why do you replace the entire list every time? You'll be forced to emit modelReset() every time and it's not great.if (index.row() < 0 || index.row() >= m_item.count())
what if the index is invalid? what if the the index has a parent? what happens if I pass an index created by another model?Why don't you just use a QStandardItemModel instead of building your own?
-
@m.kuncevicius Maybe it's because
const T &QList::at(int i) const
returns a const. Try the [] operator.Then add emit dataChanged to that data modifying method so that the view is automatically updated.
@Eeli-K Thank you for answers and suggestions!
It works right now:void ItemModel::setName(int index, QString name) { m_item[index].setName(name); QModelIndex topLeft = createIndex(index,0); emit dataChanged(topLeft, topLeft); }
@VRonin Thanks for comments on my code. Maybe you know some examples how to use QStandardItemModel because reading documentation is pretty exhausting.