Results 1 to 10 of 10

Thread: QTableView from SQLite, empty!

  1. #1
    Join Date
    Jul 2007
    Posts
    27
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Question QTableView from SQLite, empty!

    I have broken the sql/relationaltablemodel example down into four distinct steps:

    1) Create the database connection:
    = sql/relationaltablemodel/relationaltablemodel.cpp:main() =
    Qt Code:
    1. if (!createConnection())
    2. return 1;
    To copy to clipboard, switch view to plain text mode 
    = sql/connection.h:createConnection() =
    Qt Code:
    1. static bool createConnection()
    2. {
    3. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    4. db.setDatabaseName(":memory:");
    5. if (!db.open()) {
    6. QMessageBox::critical(0, qApp->tr("Cannot open database"),
    7. qApp->tr("Unable to establish a database connection.\n"
    8. "This example needs SQLite support. Please read "
    9. "the Qt SQL driver documentation for information how "
    10. "to build it.\n\n"
    11. "Click Cancel to exit."), QMessageBox::Cancel);
    12. return false;
    13. }
    14.  
    15. return true;
    16. }
    To copy to clipboard, switch view to plain text mode 
    2) Create the table in the database and add some records:
    = sql/relationaltablemodel/relationaltablemodel.cpp:main() =
    Qt Code:
    1. createRelationalTables();
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void createRelationalTables()
    2. {
    3. QSqlQuery query;
    4. query.exec("create table employee(id int primary key, name varchar(20), city int, country int)");
    5. query.exec("insert into employee values(1, 'Espen', 5000, 47)");
    6. }
    To copy to clipboard, switch view to plain text mode 
    3) Create the relational table model and initialize it:
    = sql/relationaltablemodel/relationaltablemodel.cpp:main() =
    Qt Code:
    1.  
    2. initializeModel(&model);
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void initializeModel(QSqlRelationalTableModel *model)
    2. {
    3. model->setTable("employee");
    4.  
    5. model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    6.  
    7. model->select();
    8. }
    To copy to clipboard, switch view to plain text mode 
    4) Set the QTableView to use the model:
    = sql/relationaltablemodel/relationaltablemodel.cpp:main() =
    Qt Code:
    1. QTableView *view = createView(QObject::tr("Relational Table Model"), &model);
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. QTableView *createView(const QString &title, QSqlTableModel *model)
    2. {
    3. QTableView *view = new QTableView;
    4. view->setModel(model);
    5. view->setItemDelegate(new QSqlRelationalDelegate(view));
    6. view->setWindowTitle(title);
    7. return view;
    8. }
    To copy to clipboard, switch view to plain text mode 

    Now here's my modified code, trying to do the same thing:
    1) Create the database connection:
    = mymuse/mainwindow.cpp:initMainWindow() =
    Qt Code:
    1. database = new SQLiteDB();
    2.  
    3. printf("1\n");
    4. database->createConnection();
    To copy to clipboard, switch view to plain text mode 
    = mymuse/sqlite.cpp =
    Qt Code:
    1. bool SQLiteDB::createConnection()
    2. {
    3. QString dbName = ":memory:";
    4.  
    5. QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
    6. database.setDatabaseName(dbName);
    7.  
    8. if(!database.open())
    9. {
    10. QMessageBox::critical(NULL, qApp->tr("Cannot open database"),
    11. qApp->tr("Unable to establish a connection with database '%1'.")
    12. .arg(dbName),
    13. QMessageBox::Cancel);
    14.  
    15. return false;
    16. }
    17.  
    18. return true;
    19. }
    To copy to clipboard, switch view to plain text mode 
    2) Create the table in the database and add some records:
    = mymuse/mainwindow.cpp:initMainWindow() =
    Qt Code:
    1. printf("2\n");
    2. database->createTable();
    To copy to clipboard, switch view to plain text mode 
    = mymuse/sqlite.cpp =
    Qt Code:
    1. bool SQLiteDB::execQuery(QString queryStr, bool showError)
    2. {
    3. QSqlQuery query;
    4.  
    5. if(!query.exec(queryStr))
    6. {
    7. queryErr = query.lastError();
    8. if(showError)
    9. {
    10. QMessageBox::critical(NULL, qApp->tr("Query error"),
    11. qApp->tr("%1\n%2")
    12. .arg(lastQueryError(SQL_DB_TEXT))
    13. .arg(lastQueryError(SQL_DRIVER_TEXT)),
    14. QMessageBox::Cancel);
    15. }
    16. return false;
    17. }
    18.  
    19. return true;
    20. }
    21.  
    22. void SQLiteDB::createTable()
    23. {
    24. execQuery("create table tracks (id integer primary key autoincrement, artist varchar(50), title varchar(80), "
    25. "rating integer, status integer)", true);
    26. execQuery("insert into tracks (artist, title, rating, status) "
    27. "values ('The Rolling Stones', 'Satisfaction', 33, 1)", true);
    28. }
    To copy to clipboard, switch view to plain text mode 
    3) Create the relational table model and initialize it:
    = mymuse/mainwindow.cpp:initMainWindow() =
    Qt Code:
    1. printf("3\n");
    2. database->initModel();
    To copy to clipboard, switch view to plain text mode 
    = mymuse/sqlite.cpp =
    Qt Code:
    1. void SQLiteDB::initModel()
    2. {
    3. model.setTable("tracks");
    4. model.setEditStrategy(QSqlTableModel::OnManualSubmit);
    5. model.select();
    6. }
    To copy to clipboard, switch view to plain text mode 
    4) Set the QTableView to use the model:
    = mymuse/mainwindow.cpp =
    Qt Code:
    1. printf("4\n");
    2. database->setView(trackTable);
    To copy to clipboard, switch view to plain text mode 
    = mymuse/sqlite.cpp =
    Qt Code:
    1. void SQLiteDB::setView(QTableView *table)
    2. {
    3. QSqlTableModel *tblModel = &model;
    4.  
    5. table->setModel(tblModel);
    6. table->setItemDelegate(new QSqlRelationalDelegate(table));
    7. }
    To copy to clipboard, switch view to plain text mode 

    I've created my UI using designer, and have used the multiple-inheritance model to implement it. I have a class (in mainwindow.h) called:

    class MainWindow : public QMainWindow, public Ui::MainWindow {};

    The code is in mainwindow.cpp.

    My application comes up, and numbers 1 thru 4 print out, but my QTableView remains empty, why?

    Sincerely,

    Gordon E.
    Last edited by grellsworth; 2nd July 2007 at 20:56.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView from SQLite, empty!

    Does "model" still exist when you show the table view?
    Where does "trackView" come from? Are you sure it is the same QTableView as the one you see?

  3. #3
    Join Date
    Jul 2007
    Posts
    27
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView from SQLite, empty!

    1)
    Quote Originally Posted by jacek View Post
    Does "model" still exist when you show the table view?
    Yes, "model" is defined in the class I use for sql code:

    Qt Code:
    1. class SQLiteDB : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. // Constructors and ~Destructors
    7. SQLiteDB();
    8. virtual ~SQLiteDB();
    9.  
    10. // Public Members
    11. ...
    12. };
    To copy to clipboard, switch view to plain text mode 

    2)
    Quote Originally Posted by jacek View Post
    Where does "trackView" come from?
    I created my user interface using Qt's Designer. trackView is a QTableView that I added to my layout in Designer:

    = FROM ui_mymuse.h =
    Qt Code:
    1. class Ui_MainWindow
    2. {
    3. public:
    4. ... some widgets ...
    5. QWidget *centralwidget;
    6. QTableView *trackTable;
    7. ... later ...
    8. void setupUi(QMainWindow *MainWindow)
    9. {
    10. centralwidget = new QWidget(MainWindow);
    11. trackTable = new QTableView(centralwidget);
    12. }
    13. };
    To copy to clipboard, switch view to plain text mode 

    3)
    Quote Originally Posted by jacek View Post
    Are you sure it is the same QTableView as the one you see?
    Yes, I've tried hiding/showing it in my code by using trackTable->hide() and trackTable->show() and that works correctly.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView from SQLite, empty!

    You first create the model and then the QSqlDatabase instance. Qt might not like this.

    You can change SQLiteDB::createConnection() into a static method and invoke it before you instantiate SQLiteDB.

  5. #5
    Join Date
    Jul 2007
    Posts
    27
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView from SQLite, empty!

    Quote Originally Posted by jacek View Post
    You first create the model and then the QSqlDatabase instance. Qt might not like this.

    You can change SQLiteDB::createConnection() into a static method and invoke it before you instantiate SQLiteDB.
    First of all, a BIG Thank you to jacek, for trying to help... I have had a little bit more success. My table comes up now with columns and rows, but they have no information in them, this is an improvement over a totally empty QTableView.

    I tried totally getting rid of my SQLiteDB calls, and doing all the code in one place, in my initMainWidow function (which gets called by my MainWindow contructor).

    Here's my code as it stands right now:
    Qt Code:
    1. void MainWindow::initMainWindow()
    2. {
    3. settings = new QSettings(APPNAME, DEVNAME);
    4.  
    5. QString dbName = ":memory:";
    6.  
    7. QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
    8. database.setDatabaseName(dbName);
    9.  
    10. if(!database.open())
    11. {
    12. QMessageBox::critical(NULL, qApp->tr("Cannot open database"),
    13. qApp->tr("Unable to establish a connection with database '%1'.")
    14. .arg(dbName),
    15. QMessageBox::Cancel);
    16.  
    17. return;
    18. }
    19.  
    20. QSqlQuery query;
    21. if(!query.exec("create table tracks (id integer primary key autoincrement, artist varchar(50), "
    22. "title varchar(80), rating integer, status integer)"))
    23. {
    24. printf("Error 1\n");
    25. }
    26. else
    27. {
    28. printf("OK 1\n");
    29. }
    30. if(!query.exec("insert into tracks (artist, title, rating, status) values ('The Rolling Stones', 'Satisfaction', 33, 1)"))
    31. {
    32. printf("Error 2\n");
    33. }
    34. else
    35. {
    36. printf("OK 2\n");
    37. }
    38. if(!query.exec("insert into tracks (artist, title, rating, status) values ('The Doors', 'Riders on the Storm', 75, 1)"))
    39. {
    40. printf("Error 3\n");
    41. }
    42. else
    43. {
    44. printf("OK 3\n");
    45. }
    46. query.next();
    47.  
    48.  
    49. model.setTable("tracks");
    50. model.setEditStrategy(QSqlTableModel::OnManualSubmit);
    51. model.select();
    52.  
    53. setTable(&model);
    54. }
    55.  
    56. void MainWindow::setTable(QSqlTableModel *tblModel)
    57. {
    58. trackTable->setModel(tblModel);
    59. trackTable->setItemDelegate(new QSqlRelationalDelegate(trackTable));
    60. trackTable->show();
    61. }
    To copy to clipboard, switch view to plain text mode 

    So now I get a QTableView that looks like this:
    Qt Code:
    1. -------------------------------------
    2. | 1 | 2 | 3 | 4 | 5 |
    3. -------------------------------------
    4. 1 | | | | | |
    5. -------------------------------------
    6. 2 | | | | | |
    7. -------------------------------------
    To copy to clipboard, switch view to plain text mode 

    The fact that I get five columns and two rows is promising, at least it sees that I have two records with five fields each, but why aren't the cells being populated with data?

    Sincerely,

    Gordon E.
    Last edited by jacek; 2nd July 2007 at 21:58. Reason: wrapped too long line

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView from SQLite, empty!

    Quote Originally Posted by grellsworth View Post
    QSqlRelationalTableModel model;

    model.setTable("tracks");
    model.setEditStrategy(QSqlTableModel::OnManualSubm it);
    model.select();

    setTable(&model);
    You create the model on the stack, so it gets destroyed as soon as it goes out of scope, leaving a dangling pointer behind. Better create that model on the heap (i.e. using the new operator).

  7. The following user says thank you to jacek for this useful post:

    grellsworth (3rd July 2007)

  8. #7
    Join Date
    Jul 2007
    Posts
    27
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Lightbulb Re: QTableView from SQLite, empty!

    Quote Originally Posted by jacek View Post
    You create the model on the stack, so it gets destroyed as soon as it goes out of scope, leaving a dangling pointer behind. Better create that model on the heap (i.e. using the new operator).
    Yeah, it works now... so I guess you have to follow the following (undocumented) rules:

    1) You must create your database connection before you create your (QSqlRelatinoalTableModel) model.
    2) You must create your QSqlRelationalTableModel object on the heap, using the 'new' operator.

    Did I miss anything?

  9. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView from SQLite, empty!

    Quote Originally Posted by grellsworth View Post
    2) You must create your QSqlRelationalTableModel object on the heap, using the 'new' operator.
    Not exactly. You can create it on the stack, but you must make sure it exists long enough.

  10. #9
    Join Date
    Jul 2007
    Posts
    27
    Thanks
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView from SQLite, empty!

    OK, so it should be:

    2) Make sure your QSqlRelationalTableModel object doesn't go out of scope.

  11. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView from SQLite, empty!

    Quote Originally Posted by grellsworth View Post
    OK, so it should be:

    2) Make sure your QSqlRelationalTableModel object doesn't go out of scope.
    Yes, but this isn't something that must be documented.

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.