Results 1 to 4 of 4

Thread: QsqlTableModel not fetching all rows after update

  1. #1
    Join Date
    Jan 2012
    Location
    Argentina
    Posts
    167
    Thanks
    33
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default QsqlTableModel not fetching all rows after update

    Hi everyone. Im having the following problem. I can fetch all the rows of my query and view this model with the QTableView.

    But the problem comes when, after updating a cell, the view of the model trims again only showing the first 256 rows. Here is the class:

    Qt Code:
    1. WidgetModificacion::WidgetModificacion(QWidget *parent, int tipo_tabla) :
    2. QWidget(parent),
    3. ui(new Ui::WidgetModificacion)
    4. {
    5. ui->setupUi(this);
    6. this->tipo_tabla = tipo_tabla;
    7. db = QSqlDatabase::database ("app_db");
    8. if (db.isOpen ()){
    9. model = new QSqlTableModel (this, db);
    10. switch (tipo_tabla){
    11. case 0:
    12. model->setTable ("TABLE_PRODUCTOS");
    13. break;
    14. case 1:
    15. model->setTable ("TABLE_CLIENTES");
    16. break;
    17. }
    18. model->setEditStrategy(QSqlTableModel::OnFieldChange);
    19. model->setSort (1, Qt::AscendingOrder);
    20. model->select ();
    21. while (model->canFetchMore()) model->fetchMore();
    22. this->ui->tableView->setModel (model);
    23. QStyledItemDelegate *display = new NumberRepresentation(this);
    24. ui->tableView->setItemDelegateForColumn (0, display);
    25. ui->tableView->setItemDelegateForColumn (4, display);
    26. ui->tableView->setColumnWidth(1,250);
    27. connect (this->model, SIGNAL(beforeUpdate (int, QSqlRecord &)), this, SLOT (actualizar_fecha (int, QSqlRecord &)));
    28. }
    29. else{
    30. QMessageBox::critical(0, qApp->tr("Cannot open database"),
    31. qApp->tr("Unable to establish a database connection.\n"
    32. "Llamar a Agus.\n\n"
    33. "Click Cancel to exit."), QMessageBox::Cancel);
    34. }
    35. }
    36.  
    37. WidgetModificacion::~WidgetModificacion()
    38. {
    39. delete ui;
    40. }
    41.  
    42. void WidgetModificacion::on_cerrar_clicked()
    43. {
    44. emit finaliza_modificacion (QString (":ImagesMilk/Iconos/uvacopa.png"));
    45. this->db.close ();
    46. this->close ();
    47. }
    48.  
    49. void WidgetModificacion::actualizar_fecha (int row, QSqlRecord & record){
    50. if (tipo_tabla == 0){
    51. QSqlQuery *query = new QSqlQuery (db);
    52. query->prepare ("UPDATE TABLE_PRODUCTOS SET fecha_modificacion = SYSDATE WHERE id_codigo_barra = :value");
    53. query->bindValue (":value", this->ui->tableView->model ()->data (this->ui->tableView->model ()->index (row, 0)).toString ());
    54. query->exec ();
    55. //while (model->canFetchMore()) model->fetchMore();
    56. //this->ui->tableView->setModel (model);
    57. }
    58. }
    To copy to clipboard, switch view to plain text mode 

    The code that is commented i've alredy tried it, and doesnt work. What i want is to modify the cell and stay at the same position of the table i was before the update. Thank you all in advance.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QsqlTableModel not fetching all rows after update

    The query does not add rows to the table so line 55 would achieves nothing anyway.
    Line 56 does nothing because the model pointer has not changed and the view does nothing as a result.

    QSqlTableModel does not watch the underlying data for changes. If you do not update rows through the model then it has no way to know underlying data has changed. You need to do one of these things:
    • Update through the model. Your query requires looping over all rows in the table, creating a model index, and calling setData(), but preserves current index and selection.
    • Call reset() on the model after a behind-the-model data change. This is faster but will lose the view's current cell and selection. If you have a unique ID for a row then you can cache that, reset the model, the use match() to find the unique ID and reinstate the current cell.



    Line 51 in an unnecessary heap allocation and memory leak.

  3. The following user says thank you to ChrisW67 for this useful post:

    KillGabio (17th July 2013)

  4. #3
    Join Date
    Jan 2012
    Location
    Argentina
    Posts
    167
    Thanks
    33
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QsqlTableModel not fetching all rows after update

    Thank you for replying. Line 51 modified :P

    I tried calling the reset but nothing changes. Rows showed change to 256 after the edit.

    There is no selection, the user only changes the value of one cell so i think i dont have to iterate, right? So i call setData() from the index of interest but still the same, rows trim to 256.

    Qt Code:
    1. void WidgetModificacion::actualizar_fecha (int row, QSqlRecord & record){
    2. if (tipo_tabla == 0){
    3. QSqlQuery query = QSqlQuery (db);
    4. query.prepare("UPDATE TABLE_PRODUCTOS SET fecha_modificacion = SYSDATE WHERE id_codigo_barra = :value");
    5. query.bindValue (":value", this->ui->tableView->model ()->data (this->ui->tableView->model ()->index (row, 0)).toString ());
    6. query.exec ();
    7. }
    8. //ui->tableView->reset();
    9. model->setData(model->index(row,5), QDateTime::currentDateTime().toString(),Qt::DisplayRole);
    10. while (model->canFetchMore())model->fetchMore();
    11. }
    To copy to clipboard, switch view to plain text mode 

    The value is always updated after edit and i can see that value modified but rows set to 256 anyways.

  5. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QsqlTableModel not fetching all rows after update

    You reset the QSqlTableModel and it re-executes the underlying query and, as always, fetches rows lazily. If you want to fetch all the rows again then use canFetchMore() and fetchMore().

    If you are only updating a single cell then look up its QModelIndex and call setData() and the view will look after itself. Exactly when that update is written to the underlying database and the effect on selections/current cell is a function of the model's edit strategy.

  6. The following user says thank you to ChrisW67 for this useful post:

    KillGabio (17th July 2013)

Similar Threads

  1. Replies: 0
    Last Post: 11th October 2012, 10:25
  2. Sum of rows in QSqlTableModel
    By aekilic in forum Qt Programming
    Replies: 2
    Last Post: 24th October 2010, 20:05
  3. Replies: 2
    Last Post: 25th January 2010, 20:56
  4. QSqlTableModel inserts empty rows
    By Nesbitt in forum Qt Programming
    Replies: 2
    Last Post: 6th August 2008, 12:47
  5. Fetching rows in QtreeView
    By visor_ua in forum Qt Programming
    Replies: 2
    Last Post: 5th July 2008, 18:17

Tags for this Thread

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.