[Solved] Inserting a new row of data into QSqlTableModel via QTableView edit
-
wrote on 10 Oct 2012, 11:42 last edited by
I have a function that attempts to insert a string value to a new row in a table behind a QSqlTableModel. It does so via a QTableView with a F2 style edit called programatically.
The data is not saving to the database. It shows the change in the view, but doesn't push it to the table. Edits to the existing rows don't save either.
I know this because I query the table after closing the application and my inserted row is not there.
Here is my code:
[code]
int row = periodModel->rowCount();
periodModel->insertRow(row);
QModelIndex index = periodModel->index(row, PeriodMetricsView_PeriodName);
periodView->setCurrentIndex(index);
periodView->edit(index);
[/code]Also, I did add the following to my periodModelSettings:
[code]
periodModel->setEditStrategy(QSqlTableModel::OnRowChange);
[/code]What do I need to do to get it to save the addition?
BTW:
To delete a row, I just have to do the following (it works!):
[code]
QModelIndex index = periodView->currentIndex();if (!index.isValid()) {
return;
}periodModel->removeRow(index.row());
[/code]Both my insert and remove functions are attached to QAction objects.
Thanks.
-
wrote on 10 Oct 2012, 13:26 last edited by
Hi there,
The models can't handle just the insert and remove of rows. You MUST first call beginInsertRows function for the View to handle the insertion properly.
"beginInsertRows()":http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#beginInsertRows
Note: This function emits the rowsAboutToBeInserted() signal which connected views (or proxies) must handle before the data is inserted. Otherwise, the views may end up in an invalid state.So, that might cause stuff to fail and not get stored in the View/model concept.
Good luck -
wrote on 11 Oct 2012, 02:01 last edited by
Thanks Jeroen.
Here is what I added to my QSqlTableModel subclass:
[code]
void SqlTableModel::beginInsertRow(const QModelIndex &parent, int row) {
QSqlTableModel::beginInsertRows(parent, row, row);
}void SqlTableModel::endInsertRow() {
QSqlTableModel::endInsertRows();
}
[/code]Then I added the following to the aforementioned insert function in my main window (by the way, this is the contents of a QAction triggered slot, not a rewrite of insertRows):
[code]
int row = periodModel->rowCount();
QModelIndex index = periodModel->index(row, PeriodMetricsView_PeriodName);periodModel->beginInsertRow(index, row);
periodModel->insertRow(row);
periodView->setCurrentIndex(index);
periodView->edit(index);periodModel->endInsertRow();
[/code]I did end up rearranging where the insertRow was called, as you can see.
However, that did not fix the issue.
Also, I am getting the following error message with the "period->edit(index); line (sorry I didn't realize or mention it before:
[code]
edit: index was invalid
edit: editing failed
[/code] -
wrote on 11 Oct 2012, 07:43 last edited by
Hi,
Maybe just an other idea, but try to use the insertRecord from the QsqlTableModel class. It calls insertRow etc on its own.
Also set the row on -1, this will append your data to the model.
If the view is updated it means the emit(datachanged) signal is called? If so, why not connect this signal to your saving function (slot). This way you know for sure the data is stored even if the program crashes later on. Otherwise maybe use the debugger to check the insertion of the row?
The problem of not storing data might come from a complete different part of your program and not the model at all?
greetz -
wrote on 11 Oct 2012, 11:58 last edited by
Good points, Jeroen.
I will implement those changes and test this evening and report back.
Thanks.
-
wrote on 12 Oct 2012, 03:38 last edited by
[quote author="Jeroentje@home" date="1349941438"]Hi,
The problem of not storing data might come from a complete different part of your program and not the model at all?
[/quote]True. I actually need to tinker with my database triggers and see if that makes a difference. My Qt View is hitting an "INSTEAD OF" trigger on a sqlite view. (BTW: This is the only way to use a SQL view and be able to update through it to its source table.) However, I am pretty certain that these triggers are working because I have tested inserting into the view successfully through sqlite's scripting environment outside of my application.
Anyhow, I am in the process using your ideas from earlier. So the edit event is asynchronous and I would have to be caught by connecting to the signal? That makes sense.
-
wrote on 13 Oct 2012, 04:27 last edited by
Your suspicion was correct.
The problem lied with my insert trigger for the SQL view behind the Qt QTableView object. I was using the table field name behind the SQL view to do the SQL update and not the SQL view's field name.
Thanks for your help and sorry I wasn't more aware of my database side before posting.
1/7