Results 1 to 8 of 8

Thread: Still QSqlTableModel and friends trouble

  1. #1
    Join Date
    May 2009
    Location
    USA
    Posts
    300
    Thanks
    82
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Angry Still QSqlTableModel and friends trouble

    Maybe what I am trying to do is not possible?
    Declared the following in a function:

    Qt Code:
    1. QSqlTableModel *model = new QSqlTableModel(this, logdb);
    2. QTableView *view = new QTableView();
    3. QHeaderView *header = new QHeaderView(Qt::Horizontal);
    To copy to clipboard, switch view to plain text mode 

    If it any of these are referenced within the function after they are created, all is well.
    If you try to reference say the header, in a different function, maybe to save it - crash.
    No doubt null pointer exception, but why? Shouldn't the header still exist?

    It seems the design of QSqlTableModel prevents declaring it as a class member since you can't assign a different database to it later. So it would only be good for one database.

    Am I missing something here? Or should I try a completely different approach?

  2. #2
    Join Date
    Sep 2009
    Location
    Tashkent, Uzbekistan
    Posts
    107
    Thanks
    1
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Still QSqlTableModel and friends trouble

    If you reference those objects from another thread - then yes, you should have a crash. Everything related to SQL should be kept inside one thread. See assistant for details.
    Threads and the SQL Module

    A connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported.

    In addition, the third party libraries used by the QSqlDrivers can impose further restrictions on using the SQL Module in a multithreaded program. Consult the manual of your database client for more information
    Another possible crash causes are:
    1. You don't bind headers with the model and model with database
    2. You try to perform operation on empty container.

    Hope that helps.
    -- Tanuki

    per cauda vel vaculus cauda

  3. #3
    Join Date
    May 2009
    Location
    USA
    Posts
    300
    Thanks
    82
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Still QSqlTableModel and friends trouble

    Thanks for your reply.
    I'm certainly not starting a new thread - don't think Qt is doing that on it's own.
    I think everything is bound...

    Qt Code:
    1. view->setHorizontalHeader(header);
    2. view->setModel(model);
    3. model->setTable("log");
    To copy to clipboard, switch view to plain text mode 

    And the model is bound to the database in the creation:
    QSqlTableModel *model = new QSqlTableModel(this, logdb);

    What else is there to bind?

    It doesn't crash when the first database comes up - that looks fine, just when you refer to the header you created to try and save it.

  4. #4
    Join Date
    Sep 2009
    Location
    Tashkent, Uzbekistan
    Posts
    107
    Thanks
    1
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Still QSqlTableModel and friends trouble

    Did you fill the header with the names of the columns?
    -- Tanuki

    per cauda vel vaculus cauda

  5. #5
    Join Date
    Sep 2009
    Location
    Tashkent, Uzbekistan
    Posts
    107
    Thanks
    1
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Still QSqlTableModel and friends trouble

    And actually Qt is always starting an application in its own thread. This is part of the trick
    -- Tanuki

    per cauda vel vaculus cauda

  6. #6
    Join Date
    May 2009
    Location
    USA
    Posts
    300
    Thanks
    82
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Still QSqlTableModel and friends trouble

    The header fills automatically with the column names from the database - that is ok.
    I tried the following declaration:

    Qt Code:
    1. model = new QSqlTableModel(this, logdb);
    2. view = new QTableView();
    3. header = new QHeaderView(Qt::Horizontal);
    To copy to clipboard, switch view to plain text mode 

    Now, it opens previously created/saved databases and saves the open db/view header without crashing.

    It will also create a new database if I do it from a lineEdit/button on the mainwindow ok,
    but if I try that same thing from a lineEdit/button connected with signal/slot from a dialog, then it crashes when it tries to save the existing open header.
    Something different is happening when done from the dialog.
    The method is called the same way though.

    Qt Code:
    1. // method called from mainwindow
    2. void MainWindow::addLog() {
    3. if (ui->mwCall->text() != "") {
    4. QMessageBox::information(this, "QtLogger", tr("Last QSO not saved. Please save or clear before creating a new log."));
    5. }
    6. QString log = ui->leNewLog->text();
    7. ControlDB ctrl;
    8. ctrl.createLogDB(log, ctrlConn);
    9. openLog(log); // this is where the model/header/view are created on the heap after existing header is saved and then model/view/header are deleted
    10. ui->leNewLog->setText("");
    11. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // this is method called from the dialog - same functionality as above
    2. void MainWindow::newLog(QString log) {
    3. if (ui->mwCall->text() != "") {
    4. QMessageBox::information(this, "QtLogger", tr("Last QSO not saved. Please save or clear before creating a new log."));
    5. }
    6. ControlDB ctrl;
    7. ctrl.createLogDB(log, ctrlConn);
    8. openLog(log);
    9. }
    To copy to clipboard, switch view to plain text mode 

    So you can see everything that goes on....

    Qt Code:
    1. void MainWindow::openLog(QString logName) {
    2. ControlDB ctrl;
    3. QString openLog = ctrl.getOpenLog(ctrlConn);
    4.  
    5. if (openLog != "") {
    6. QSqlDatabase db = QSqlDatabase::database(hdrConn);
    7. db.setDatabaseName("header.sqlite");
    8. db.open();
    9. ha = header->saveState();
    10.  
    11. QSqlQuery query(db);
    12. query.prepare("SELECT count(*) from header where headerLog = ?");
    13. query.addBindValue(logName);
    14.  
    15. query.exec();
    16. query.last();
    17. int cnt = query.value(0).toInt();
    18.  
    19. if (cnt == 0) {
    20. query.prepare("INSERT into header(positions, headerLog) VALUES (?, ?)");
    21. query.addBindValue(ha);
    22. query.addBindValue(logName);
    23. query.exec();
    24. }else{
    25. query.prepare("UPDATE header set positions=? where headerLog=? ");
    26. query.addBindValue(ha);
    27. query.addBindValue(logName);
    28. query.exec();
    29. query.last();
    30. qDebug() << "saveHeader error 3 = " << query.lastError();
    31. }
    32. db.close();
    33.  
    34. QSqlDatabase openDB = model->database();
    35. openDB.close();
    36.  
    37. delete header; // these only deleted if there was an open db and after header was saved.
    38. delete view;
    39. delete model;
    40. }
    41.  
    42. QSqlDatabase hdrdb = QSqlDatabase::database(hdrConn);
    43. QSqlQuery query(hdrdb);
    44. query.prepare("SELECT count (*) from header where headerLog = ?");
    45. query.addBindValue(logName);
    46. query.exec();
    47. query.last();
    48. int cnt = query.value(0).toInt();
    49.  
    50. ctrl.createConnection(logName + ".log", logName);
    51. QSqlDatabase logdb = QSqlDatabase::database(logName);
    52. logdb.setDatabaseName(logName + ".log.sqlite");
    53. logdb.open();
    54.  
    55. model = new QSqlTableModel(this, logdb);
    56. view = new QTableView();
    57. header = new QHeaderView(Qt::Horizontal);
    58.  
    59. view->setHorizontalHeader(header);
    60. //etc
    To copy to clipboard, switch view to plain text mode 

    Is Qt starting a new thread for the dialog - could that be the problem?
    The dialog passes the new db name to a function in the mainwindow class just like the lineEdit/button on the mainwindow does.

  7. #7
    Join Date
    Jul 2009
    Posts
    139
    Thanks
    13
    Thanked 59 Times in 52 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Still QSqlTableModel and friends trouble

    Qt Code:
    1. delete header; // these only deleted if there was an open db and after header was saved.
    2. delete view;
    3. delete model;
    To copy to clipboard, switch view to plain text mode 
    model is a child of view, so will be deleted when view is deleted. The documentation doesn't say but I suspect that the view also takes ownership of the header. Probably, just delete the view and the other two will be deleted automatically. OR you could use the QPointer class to make sure you're not redeleting.

  8. #8
    Join Date
    Oct 2009
    Posts
    151
    Thanks
    6
    Thanked 13 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Still QSqlTableModel and friends trouble

    Your QSqlTableModel is owned by the MainWindow object and will be automatically destroyed when this is closed (line 56)
    the QTableView and QHeaderView have no parents and will need to be deleted explicitly.
    By deleting the model in line 40 you are unbalancing the call stack which will make the application crash.
    Putting delete operators inside an if statement is rarely a good idea, if they are used at all they should unconditionally delete the object created by new when the object is no longer wanted.

    A better solution would be to give the table and hearde views parents and let QT deal with the garbage collection.
    Last edited by JD2000; 8th January 2010 at 15:26.

Similar Threads

  1. Trouble with "INSERT" by QSqlTableModel
    By AD in forum Qt Programming
    Replies: 12
    Last Post: 10th November 2008, 08:21
  2. Friends Problem in Installing Qt 4.3.2 on Mac Os X
    By nareshqt in forum Installation and Deployment
    Replies: 1
    Last Post: 11th April 2008, 06:35
  3. Hello friends, I have a problem in QT
    By praveen in forum Installation and Deployment
    Replies: 4
    Last Post: 2nd April 2008, 08:36
  4. QSqlTableModel
    By raphaelf in forum Qt Programming
    Replies: 4
    Last Post: 4th March 2006, 12:35

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
  •  
Qt is a trademark of The Qt Company.