[Development] Regression / Behavioral Change in QSqlTableModel / QTableView in Qt 5
Mark Brand
mabrand at mabrand.nl
Tue Sep 11 14:49:22 CEST 2012
Maemi Carrer wrote:
>> ... each edit causes the table to be requeried and the model reset, which
>> breaks navigation in the view.
> Do you mind elaborating in which way this breaks navigation?
In Qt 4, QSqlTableModel calls select() immediately after submitting
changes to the database. This invokes QSqlQueryModel::setQuery(). In the
process, the rows and columns of the model are removed and replaced. The
view (QTableView) is notified about this by signals. The current index
and selections are therefore lost.
>> It sounds like you are using OnFieldChange or OnRowChange strategy. This is
>> by design. The deleted row remains in the cache until select() is called
>> again.
> I see. Is there any possibility to update the model (so the row is removed in
> the view, not just cleared out) without 'resetting' the model using select()?
>
> I just want to have the row deleted (yes, at the cost of losing navigation and
> selection in the view), but without having to repopulate the data from the
> database (which is implied by select()).
If you just want the Qt 4 behavior, then you should just use select()
like it does.
You might also consider using QSortFilterProxyModel to hide the deleted
rows.
Now, what you are asking for is a way to make QSqlTableModel remove
model rows corresponding to submitted DELETEs. There are some things to
consider.
First of all, there is no guarantee that a record is deleted in the
database afterwards, perhaps because a foreign key prevents it, a
database trigger reinterprets the DELETE, or another user puts the
record back. If the row were removed from the model, the user would have
no way to see what the actual status of the record is.
We could consider removing the row from the model only after verifying
that the corresponding record no longer exists in the database table.
This is a possibility, but it would complicate the mapping between the
query result set and the table model. Also, it removes information from
the model about what has been done to the records returned by the last
select(). If we were to add this, I think it should be an option. What
do you think? If you would like to pursue this, could you follow this up
with a feature request at http://bugreports.qt-project.org?
>>> Inserations for example using insertRecord() are not reflected as well
>>> (no visible changes in the view, although data is added to the table).
>> This is not the expected behavior and I cannot reproduce it. Can you provide
>> an example?
> I tried to boil down the code to a simple example and I now can nail down the
> problem. It only affects tables having an AUTOINCREMENT primary key, causing
> an empty row to be inserted (with an exclamation mark in the view, same as
> for a deleted row) and a select() is required to get the actual data
> into the view
> (and obviously the model as well).
>
> Tables having a primary key not beeing AUTOINCREMENT (although they are
> set by the database as well) seem to be not effected (data is shown
> immediately).
That's interesting. When the model refreshes the affected row after
submitting changes, it uses the primary key values of the record to get
the changes from the database table. It obviously doesn't have the key
values for AUTOINCREMENT. Sound likes a bug. Maybe it can be solved at
least partly by getting the inserted IDs in these cases. Could you
please make a bug for this on http://bugreports.qt-project.org?
regards,
Mark
More information about the Development
mailing list