Results 1 to 7 of 7

Thread: QSqlTableModel::insertRows, using the row parameter

  1. #1
    Join Date
    Sep 2012
    Location
    Iran, Tehran
    Posts
    76
    Thanks
    17
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default QSqlTableModel::insertRows, using the row parameter

    Hello

    I have a QTableView with a QSqlTableModel as its model.

    The problem is that the newly added rows will be displayed at the end of the view, no matter what is the value of row.

    Documentation of QSqlTableModel::insertRows says: "Inserts count empty rows at position row." and in QAbstractItemModel::insertRows it says: "inserts count rows into the model before the given row."

    If "into the model" means it has no predicted effect on the view, what's the use of row?

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

    Default Re: QSqlTableModel::insertRows, using the row parameter

    The function does exactly what it says it does. The view may be sorting the rows, you may be using an invalid row number etc. We don't know unless you can provide a small example that demonstrates the problem. This, for example, works fine:
    Qt Code:
    1. #include <QtGui>
    2. #include <QtSql>
    3. #include <QDebug>
    4.  
    5. void createConnection()
    6. {
    7. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    8. db.setDatabaseName(":memory:");
    9. if (db.open()) {
    10. QSqlQuery query;
    11. query.exec("create table person (id int, "
    12. "firstname varchar(20), lastname varchar(20), primary key(firstname, lastname))");
    13. query.exec("insert into person values(101, 'Danny', 'Young')");
    14. query.exec("insert into person values(102, 'Christine', 'Holand')");
    15. query.exec("insert into person values(103, 'Lars', 'Gordon')");
    16. query.exec("insert into person values(104, 'Roberto', 'Robitaille')");
    17. query.exec("insert into person values(105, 'Maria', 'Papadopoulos')");
    18. }
    19. }
    20.  
    21. int main(int argc, char *argv[])
    22. {
    23. QApplication app(argc, argv);
    24. createConnection();
    25.  
    26. model.setTable("person");
    27. model.setEditStrategy(QSqlTableModel::OnManualSubmit);
    28. model.select();
    29.  
    30. QTableView view;
    31. view.setModel(&model);
    32. view.resize(640, 480);
    33. view.show();
    34.  
    35. model.insertRow(2);
    36. model.insertRow(5);
    37.  
    38. return app.exec();
    39. }
    To copy to clipboard, switch view to plain text mode 
    If you use the other edit strategies then you can only insert one row at a time (see QSqlTableModel::insertRows()) .

  3. #3
    Join Date
    Sep 2012
    Location
    Iran, Tehran
    Posts
    76
    Thanks
    17
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Smile Re: QSqlTableModel::insertRows, using the row parameter

    Thanks

    Now I know QSqlTableModel::insertRows() adds a new empty row where it is given by the row parameter, but when I set data for that row, the position of the row changes and it will appear at the end (actually it happens when I set data for the path column in the table, you can see table creation command below).
    I think the view is not sorted because QTableView::isSortingEnabled() returns false.

    The code for creating table:
    Qt Code:
    1. bool LibMan::createLib(const QString &libName)
    2. {
    3. QSqlQuery query;
    4.  
    5. return query.exec("CREATE TABLE " + libName + "(\
    6. id INTEGER PRIMARY KEY AUTOINCREMENT,\
    7. title VARCHAR(255),\
    8. path VARCHAR(255) NOT NULL)");
    9. }
    To copy to clipboard, switch view to plain text mode 

    Inserting new data:
    Qt Code:
    1. void LibMan::insertRecords()
    2. {
    3. lastIndex = 0;
    4.  
    5. if (insertionList->count() > 1)
    6. {
    7. tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
    8. }
    9.  
    10. tabModel->insertRows(0, insertionList->count());
    11.  
    12. tabModel->submitAll();
    13.  
    14. tabModel->setEditStrategy(QSqlTableModel::OnRowChange);
    15. }
    To copy to clipboard, switch view to plain text mode 

    Initializing:
    Qt Code:
    1. tabModel = new SqlTableModel(this);
    2. tabModel->setTable("pap");
    3. tabModel->setHeaderData(1,Qt::Horizontal, QObject::tr("Title"));
    4. tabModel->setHeaderData(2, Qt::Horizontal, QObject::tr("Location"));
    5. tabModel->setEditStrategy(QSqlTableModel::OnRowChange);
    6.  
    7. proxyModel = new SortFilterProxyModel(this);
    8. proxyModel->setSourceModel(tabModel);
    9. proxyModel->setDynamicSortFilter(true);
    10. proxyModel->setFilterKeyColumn(1);
    11.  
    12. ui->tableView->setModel(tabModel);
    13. // ui->tableView->setModel(proxyModel);
    14.  
    15. ui->tableView->setColumnHidden(0, true);
    16. ui->tableView->resizeColumnsToContents();
    17.  
    18. // if (ui->tableView->isSortingEnabled()) return;
    19.  
    20. QObject::connect(tabModel, SIGNAL(primeInsert(int,QSqlRecord&)), this, SLOT(fill(int,QSqlRecord&)));
    21. QObject::connect(proxyModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(selectEdited(QModelIndex,QModelIndex)));
    22.  
    23. // tabModel->insertRows(24,1);
    To copy to clipboard, switch view to plain text mode 

    SqlTableModel is a subclass of QSqlTableModel, does nothing special except coloring empty fields.

    And the slot fill():
    Qt Code:
    1. void LibMan::fill(int row, QSqlRecord &record)
    2. {
    3. record.setValue(2, insertionList->at(lastIndex++));
    4. }
    To copy to clipboard, switch view to plain text mode 


    Added after 55 minutes:


    ChrisW67, I have changed your example and now it is a working example that demonstrates the problem:
    Qt Code:
    1. #include <QtGui>
    2. #include <QtSql>
    3. #include <QDebug>
    4.  
    5. void createConnection()
    6. {
    7. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    8. db.setDatabaseName("D:\\tempDB\\mydb5");
    9. if (db.open()) {
    10. QSqlQuery query;
    11. QString str = "pap";
    12.  
    13. query.exec("CREATE TABLE " + str + "(\
    14. id INTEGER PRIMARY KEY,\
    15. title VARCHAR(255),\
    16. path VARCHAR(255) NOT NULL)");
    17.  
    18. query.exec("insert into pap values('1', 't1', 'test1')");
    19. query.exec("insert into pap values('2', 't2', 'test2')");
    20. query.exec("insert into pap values('3', 't3', 'test3')");
    21. query.exec("insert into pap values('4', 't4', 'test4')");
    22. query.exec("insert into pap values('5', 't5', 'test5')");
    23. }
    24. }
    25.  
    26. int main(int argc, char *argv[])
    27. {
    28. QApplication app(argc, argv);
    29. createConnection();
    30.  
    31. model.setTable("pap");
    32. model.setEditStrategy(QSqlTableModel::OnRowChange);
    33. model.select();
    34.  
    35. QTableView view;
    36. view.setModel(&model);
    37. view.setEditTriggers(QAbstractItemView::DoubleClicked);
    38. view.resize(640, 480);
    39. view.show();
    40.  
    41. model.insertRows(2,1);
    42. model.setData(model.index(0,2), "temp");
    43.  
    44. return app.exec();
    45. }
    To copy to clipboard, switch view to plain text mode 

    Now if you change the data in the incomplete row, it will appear at the end of the list. It seems that it is sorted by column id, but sorting is not enabled
    Last edited by Ashkan_s; 10th September 2012 at 10:52.

  4. #4
    Join Date
    Sep 2012
    Location
    Iran, Tehran
    Posts
    76
    Thanks
    17
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QSqlTableModel::insertRows, using the row parameter

    Row numbers are meaningful inside model, not inside the underlying database. The order in which records retrieved from database affects the row numbers in model (view). Therefore, submitting data into DB may change the row number.
    Is it true?

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

    Default Re: QSqlTableModel::insertRows, using the row parameter

    Is it true?
    Yes. There is no notion of a "row number" in the SQL table. When the data is submitted the model re-runs a select query ('select * from table' without sorting) and the table rows are returned in a system dependent indeterminate order. In many cases the rows are returned in creation order or order of an internal id (like you see) but some databases return rows in order of primary key if there is one.

    You can use QSqlTableModel::setSort() to impose a simple sort order on retrieval, i.e. it adds an ORDER BY clause to the query, but you will need to have a column to sort in your data. Alternatively you can use the view to sort based on the same column data.

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

    Ashkan_s (12th September 2012)

  7. #6
    Join Date
    Sep 2012
    Location
    Iran, Tehran
    Posts
    76
    Thanks
    17
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QSqlTableModel::insertRows, using the row parameter

    Well, using QSqlTableModel::insertRows() one can only place non-submitted records in the given row, when this might be useful? I mean usually for inserting new rows we use the value of 0 for the row why should one want to change this value to e.g 10 when both might be changed after submitting?
    Last edited by Ashkan_s; 12th September 2012 at 07:16. Reason: spelling corrections

  8. #7
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,543
    Thanks
    13
    Thanked 1,577 Times in 1,506 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QSqlTableModel::insertRows, using the row parameter

    It is useful if the displayed position of the new row reflects where it will be seen after it is committed (because you are sorting in a consistent way), or indicates some relationship to the rows around it, or puts the new row near another for ease of reference while filling the row before commit, or provides a consistent location that a new row appears e.g always at the top/bottom of the table/visible rows, or the new row uses primeInsert() to gain default values and appears in the expected place for those values...

    Not all models have the behaviours imposed on QSqlTableModel by the underlying SQL engine. Other models insert item at row n, and that's where it stays.

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

    Ashkan_s (12th September 2012)

Similar Threads

  1. QSortFilterProxyModel::insertRows always adds rows to the end
    By Agnostic Pope in forum Qt Programming
    Replies: 1
    Last Post: 7th May 2012, 23:23
  2. Rowcount and insertrows differences
    By tonnot in forum Qt Programming
    Replies: 2
    Last Post: 14th April 2011, 08:56
  3. Replies: 0
    Last Post: 13th April 2011, 08:47
  4. Replies: 8
    Last Post: 30th March 2011, 20:06
  5. QTable insertRows issue
    By PrimeCP in forum Qt Programming
    Replies: 1
    Last Post: 18th April 2007, 09:08

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.