October 8, 2010

Dieter Dieter
Lab Rat
93 posts

[Solved] The “best” way to programmatically refresh a QSqlQueryModel when the content of the query changes

 

I was wondering what the appropriate way to refresh a QTableView using a QSqlQueryModel would be when the result of the query would change triggered by some external event outside the Qt app?

I’m aware that:

  • QSqlQueryModel ::setQuery can be called but why should I parse a new query just to refresh it?
  • QTableView::setModel can be used but why should I set a new model only to refresh it?
  • QSqlQueryModel ::reset can be used but this is a protected method and would completely reset the model including information about the header line etc.

The model/view architecture of Qt seems to have a very complex and well documented architecture but I just cannot seem to find the proper way to do this.

8 replies

October 18, 2010

Andre Andre
Area 51 Engineer
6031 posts

I think you’ll have to stick to the setQuery method. At first, you say that the query would change because of some external event. Then why is it weird that you have to set it again? It is not refreshing if the query itself has changed, is it?
How much that costs, would depend on your db engine I think. It may – I am not sure here – also depend on how you set your query. If you use setQuery (QSqlQuery) and bind the arguments that will change, your database may be able to optimize and not parse the SQL again. If not, using a view in your database could help too.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

October 18, 2010

Luca Luca
Ant Farmer
589 posts

In my projects with mysql I use setQuery to update the data.
With slow query, the first setQuery is slow but the next are very faster because mysql keep in cache the table used in query.

October 18, 2010

Dieter Dieter
Lab Rat
93 posts

I would also guess that the performance impact very much depends on how the Qt database driver is implemented and the internals of the database itself.
I also agree that setQuery typically should not have a huge performance impact but why should this not be encapsulated in the Qt model itself. In my impression a simple public refresh method just seems to be missing.
To give a an example I use the situation I came across when issuing this message.
I use a rather complex SQL query to an Oracle Database to retrieve data that will be used in a graph.
The graph will be updated every second using a timer with the latest data and update the graph.
The columns and the query are constant and I would only like to “refresh” the data will the latest values.

October 18, 2010

ZapB ZapB
Robot Herder
1355 posts

Another way is to prepare a database view of your complex query and then use a QSqlTableModel on the view. This class does expose an exec() method to re-run the query.

 Signature 

Nokia Certified Qt Specialist
Interested in hearing about Qt related work

October 18, 2010

ZapB ZapB
Robot Herder
1355 posts

Oops sorry, the method is actually select() not exec(). /me should check the docs.

 Signature 

Nokia Certified Qt Specialist
Interested in hearing about Qt related work

November 6, 2010

xj.liu.yang xj.liu.yang
Lab Rat
1 posts

QSqlTableModel::select() use setQuery( QString, QSqlDatabase ) method refresh contents. I guess you could do it the same way.

April 19, 2013

Galbarad Galbarad
Lab Rat
19 posts

Hi all
I have similar question I am use QTableView + QSqlQuery when I set query at first time I allow fetch only first 10 rows from query, after that according user decides I can fetch next few rows, but my QTableView is not refreshed after fetch. I can’t use setQuery because I do not what run sql yet one time to get result that I already have.
I try to use something like this

  1. emit dataChanged(createIndex(OldRowCnt, 1), createIndex(RowCount, HeaderCount));

but this has no result

thank you for future help )

April 22, 2013

Galbarad Galbarad
Lab Rat
19 posts

beginInsertRows solve my problem, I am call it after fetch

  1. bool cOciQModel::fetch(int Cnt, bool SilentMode) {
  2.     if (RowCount && !query->seek(RowCount - 1)) {
  3.         LastError = QString("Can't goto [%1] position").arg(QString::number(RowCount - 1));
  4.         return false;
  5.     }
  6.  int OldRowCnt = RowCount;
  7.     int Count = Cnt + 1;
  8.     while (--Count && !AllDataFetched) {
  9.   AllDataFetched = !query->next();
  10.   if (!AllDataFetched) {
  11.    ++RowCount;
  12.   }
  13.     }
  14.  
  15.  if (!SilentMode) {
  16.   beginInsertRows(QModelIndex(), OldRowCnt, RowCount);
  17.   endInsertRows();
  18.  }
  19.  
  20.     return true;
  21. }

 
  ‹‹ [Solved] Warning C4946: reinterpret_cast used between related classes when using qobject_cast      Binary-coded decimal for Qt ››

You must log in to post a reply. Not a member yet? Register here!