Results 1 to 8 of 8

Thread: QTableView/QSqlQueryModel

  1. #1
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default QTableView/QSqlQueryModel

    I have modified the QT example "querymodel" for my database. I issue a select statement that joins two tables and displays the result in a QTableView. I can edit a field and the program updates the appropriate table.

    My problem is that when the edited field is exited, the screen is refreshed and the view returns to the first record in the query. There are over 4,000 records in the DB so needless to say it gets kind of old scrolling back down to edit a field in a another record near the bottom of the query.

    Is there a way to update the tables and not update the QTableView? Or is there a way to control what the refreshed view displays?

    Thanks in advance for any help!!!

    Norm

  2. #2
    Join Date
    Jan 2008
    Posts
    33
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableView/QSqlQueryModel

    if thats the case my advice is that dont use QSqlQuerymodel just use ordinary table and save the record into temporary record...

    thats my opinion..

  3. #3
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView/QSqlQueryModel

    QSqlQueryModel is a read-only model so apparently you commit data by hand, don't you? I can understand the problem because re-setting the query causes the whole data model to be rebuilt. From table view's point of view this is basically same than switching to whole different model.
    J-P Nurmi

  4. #4
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: QTableView/QSqlQueryModel

    From the Qt docs for QSqlQueryModel:
    The model is read-only by default. To make it read-write, you must subclass it and reimplement setData() and flags().
    Which is what I've done. Works great.


    Quote Originally Posted by jpn View Post
    .... re-setting the query causes the whole data model to be rebuilt. From table view's point of view this is basically same than switching to whole different model.
    You're exactly right. I've thought of saving the row number or the index of the row and then performing a seek after refreshing the model to at least have the previous record on the screen when the model is redisplayed but I don't know how you perform a seek on records displayed with a select statement.

  5. #5
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView/QSqlQueryModel

    So how do you update the data at the moment? Do you reset the query or..? It would work out of the box if you were able to handle it by emitting dataChanged().
    J-P Nurmi

  6. #6
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: QTableView/QSqlQueryModel

    Here is some of my code. As I said in my first post, I have just modified (slightly) one of the examples in the QT docs.

    Qt Code:
    1. Qt::ItemFlags EditableSqlModel::flags(const QModelIndex &index) const
    2. {
    3. Qt::ItemFlags flags = QSqlQueryModel::flags(index);
    4. if (index.column() == 1 || index.column() == 2 || index.column() == 3 || index.column() == 4 || index.column() == 5)
    5. flags |= Qt::ItemIsEditable;
    6. return flags;
    7. }
    8.  
    9. bool EditableSqlModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
    10. {
    11. if (index.column() < 1 || index.column() > 5)
    12. return false;
    13.  
    14. QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
    15. int id = data(primaryKeyIndex).toInt();
    16. clear();
    17. bool ok=FALSE;
    18. if (index.column() == 1) ok = setName(id, value.toString());
    19. if (index.column() == 2) ok = setCountry(id, value.toString());
    20. if (index.column() == 3) ok = setTotal(id, value.toDouble());
    21. if (index.column() == 4) ok = setMachine(id, value.toString());
    22. if (index.column() == 5) ok = setOs_vendor(id, value.toString());
    23. refresh();
    24. return ok;
    25. }
    26.  
    27. void EditableSqlModel::refresh()
    28. {
    29. setQuery("SELECT host.id, user.name, user.country, host.total, host.machine, host.os_vendor FROM host left join user on host.id = user.id where user.name IS NOT NULL order by host.total");
    30. }
    31.  
    32. bool EditableSqlModel::setName(int id, const QString &name)
    33. {
    34. QSqlQuery query;
    35. query.prepare("update user set name = ? where id = ?");
    36. query.addBindValue(name);
    37. query.addBindValue(id);
    38. return query.exec();
    39. }
    40.  
    41. bool EditableSqlModel::setCountry(int id, const QString &Country)
    42. {
    43. QSqlQuery query;
    44. query.prepare("update user set country = ? where id = ?");
    45. query.addBindValue(Country);
    46. query.addBindValue(id);
    47. return query.exec();
    48. }
    49.  
    50. bool EditableSqlModel::setTotal(int id, const double &Total)
    51. {
    52. QSqlQuery query;
    53. query.prepare("update host set total = ? where id = ?");
    54. query.addBindValue(Total);
    55. query.addBindValue(id);
    56. return query.exec();
    57. }
    58.  
    59. bool EditableSqlModel::setMachine(int id, const QString &Machine)
    60. {
    61. QSqlQuery query;
    62. query.prepare("update host set machine = ? where id = ?");
    63. query.addBindValue(Machine);
    64. query.addBindValue(id);
    65. return query.exec();
    66. }
    67.  
    68. bool EditableSqlModel::setOs_vendor(int id, const QString &Os_vendor)
    69. {
    70. QSqlQuery query;
    71. query.prepare("update host set os_vedor = ? where id = ?");
    72. query.addBindValue(Os_vendor);
    73. query.addBindValue(id);
    74. return query.exec();
    75. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView/QSqlQueryModel

    The problem is that QSqlQueryModel represents content of a QSqlQuery. It is insufficient to emit dataChanged() because the content of the original query hasn't changed so nothing would change in the view anyway. So, one is forced to set a new query to get anything updated. On the other hand, setting a new query means rebuilding the model from scratch and losing current state of the view. I'm afraid I can't come up with any better solution than storing and restoring current index, possibly together with scroll bar values to retain exactly the same viewport position.
    J-P Nurmi

  8. #8
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: QTableView/QSqlQueryModel

    I'm going to try experimenting with the viewport position.

    Thank you very much for taking time to think about my problem.

    Norm

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.