Unsolved Custom Table Model
-
I see. So doing something like this would update every cell in the table?
QModelIndex i = this->index(0,0,QModelIndex()); QModelIndex p = this->index(students.size()-1,1,QModelIndex());
-
Yes, but for this you should use begin/endResetModel() and you should only use it when you really need it. Make sure to only call dataChanged() for stuff you need.
-
So are you saying that ideally I should only emit dataChanged() on the rows affected?
-
Hi,
@EaccB said in Custom Table Model:
So are you saying that ideally I should only emit dataChanged() on the rows affected?
Yes, this will avoid unneeded processing and updating of the GUI for things that did not change.
-
Ok, here's what I've done:
void TestModel::update(int row){ QModelIndex i = this->index(row,0,QModelIndex()); QModelIndex p = this->index(row,1,QModelIndex()); emit dataChanged(i,p); }
This way, only the affected row is updated.
-
dataChange takes a range so here you always emit that the it starts from the first up to the row you pass as parameter. Is it really always the case ?
-
I edited my answer.
-
When emitting dataChanged(i,p) for the deleted row only, how is it that the following rows move up? Wouldn't that require a dataChanged(i,p) for the whole table?
-
@EaccB said in Custom Table Model:
When emitting dataChanged(i,p) for the deleted row only,
You did not read my link. You must not call dataChanged() when removing a row.
-
Then what do I use to signal to the view that the model has been updated? I've removed dataChanged() and replaced it with layoutChanged() which seems to work fine.
To avoid any confusion, the table itself is read-only and should only reflect the contents of the students vector inside StudentManager. Any changes to the data (i.e. add student, edit student, remove student) are done directly on the students vector.
-
@EaccB said in Custom Table Model:
Then what do I use to signal to the view that the model has been updated?
dataChanged() as explained above.
-
Ok, I'm really confused. You said that I shouldn't use dataChanged() when removing a row. So, what should I do when an element is removed from the vector? Or are you saying that I should emit dataChanged from the class which owns the vector and connect it to a slot in the Model?
-
@EaccB said in Custom Table Model:
So, what should I do when an element is removed from the vector?
You really really should read the documentation. I already gave a the link two times...: https://doc.qt.io/qt-5/model-view-programming.html#inserting-and-removing-rows
-
@EaccB
To reiterate what @Christian-Ehrlicher is telling you. The signal code in a model has to depend on whether you are updating an existing row which is already there and will remain there, versus if you inserting or deleting a row.dataChanged()
is only for same rows, with values in columns changing.For inserting/deleting rows you must use
begin/endInsert/RemoveRows()
instead.Views, for example, need to know this and react differently according as the model reports its rows are being updated or are being deleted/inserted. You can imagine the action they take will differ between these cases.
-
I think we got out wires crossed. By "update the vector", I meant add and remove elements, as well as editing existing items. This is why I was confused when @Christian-Ehrlicher suggested using dataChanged(), which he had previously told me not to use for removing elements.
If I add an element directly to the vector, do I still need to call insertRows() from the model?
-
@EaccB said in Custom Table Model:
which he had previously told me not to use for removing elements.
where?
If I add an element directly to the vector, do I still need to call insertRows() from the model?
Yes, as clearly written in the docs.
-
You must not call dataChanged() when removing a row.
-
@EaccB Sorry, I over read the not
This statement is correct.
-
If you use the model-as-interface-on-existing-data
@EaccB said in Custom Table Model:
editing existing items
- The item that owns the data should emit a signal after the item is modified, the model will connect to this signal and emit
dataChanged
I meant add and remove elements
- The item that owns the data should emit a signal before the item is added/removed, the model will connect to this signal and call
beginInsertRows
/beginRemoveRows
- The item that owns the data should emit a signal after the item is added/removed, the model will connect to this signal and call
endInsertRows
/endRemoveRows
- The item that owns the data should emit a signal after the item is modified, the model will connect to this signal and emit
-
Unless the point of your exercise is to create a model - why don't you use built in sqlite for data storage (be it in memory or in a file) and use generic QSqlTableModel, where you don't have to worry about anything? Seems like much less work...