Congratulations to our 2022 Qt Champions!

[Solved] dataChanged emitted before data being changed in model

  • I have a subclass of QSqlTableModel that does not reimplement the setData() method and therefore does not reimplement dataChanged(). I mention this up front only because most info I've read about subclassing a model says to always reimplement these two methods. If I did, they would be redundant, simply calling they're parent classes methods. That being said, here is my issue:

    I have a Sqlite3 view connected to a subclassed model type object (see above), lets call it the summary model. It's purpose is to summarize the amount entered into a different model of the same class (lets call it the detail model.)

    I have connected the dataChanged signal on the detail model to a slot in my widget. This slot runs a select() on my summary model so that it will update (that is, internally rerun the Sqlite3 view query that hits the detail model's internal table and populate).

    The problem is it is not getting updated upon running select().

    I have debugged this in Qt Creator and found that the issue is the detail model's dataChanged signal is called before the detail model's table is updated.

    To find this, I ran the same SQL used by my summary model's Sqlite3 view in the Sqlite emulator while pausing the debugger on the aforementioned slot. It isn't until I run (F5) that it updates the detail table.

    The net effect is my summary Qt view is getting updated with the first changes after the second changes have been made.

    Is this normal? If so, what signal should I connect to run the select after the change?

  • Did you set QSqlTableModel's editStrategy property to QSqlTableModel::OnFieldChange or QSqlTableModel::OnRowChange ?

    The actual change to the database is made by the (virtual) function QSqlTableModel::submitAll(), so you can put your updating code there.

  • Actually, I'm surprised to find that I don't have the edit strategy set on either model. For some reason I removed it about a month ago (I checked my older source files.)

    I'm using it in another area, but I could have sworn it was still there.

    Anyhow, so all I would do is reimplement submitAll() and call my update code after the QSqlTableModel::submitAll() call?


  • The method submitAll is not virtual, but submit is, so I was able to reimplement it. My plan now is to create a signal and emit it from the reimplemented submit method on the detail model.

    I'll connect to that signal within my form and call the proper update/select statements on my summary model.

  • Fantastic!!!

    That worked alexisdm! Thanks so much for the tip!

Log in to reply