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() =
Code:
if (!createConnection())
return 1;
= sql/connection.h:createConnection() =
Code:
static bool createConnection()
{
db.setDatabaseName(":memory:");
if (!db.open()) {
QMessageBox::critical(0, qApp
->tr
("Cannot open database"),
qApp->tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
return false;
}
return true;
}
2) Create the table in the database and add some records:
= sql/relationaltablemodel/relationaltablemodel.cpp:main() =
Code:
createRelationalTables();
Code:
void createRelationalTables()
{
query.exec("create table employee(id int primary key, name varchar(20), city int, country int)");
query.exec("insert into employee values(1, 'Espen', 5000, 47)");
}
3) Create the relational table model and initialize it:
= sql/relationaltablemodel/relationaltablemodel.cpp:main() =
Code:
initializeModel(&model);
Code:
{
model->setTable("employee");
model->select();
}
4) Set the QTableView to use the model:
= sql/relationaltablemodel/relationaltablemodel.cpp:main() =
Code:
{
view->setModel(model);
view->setWindowTitle(title);
return view;
}
Now here's my modified code, trying to do the same thing:
1) Create the database connection:
= mymuse/mainwindow.cpp:initMainWindow() =
Code:
database = new SQLiteDB();
printf("1\n");
database->createConnection();
= mymuse/sqlite.cpp =
Code:
bool SQLiteDB::createConnection()
{
database.setDatabaseName(dbName);
if(!database.open())
{
QMessageBox::critical(NULL, qApp
->tr
("Cannot open database"),
qApp->tr("Unable to establish a connection with database '%1'.")
.arg(dbName),
return false;
}
return true;
}
2) Create the table in the database and add some records:
= mymuse/mainwindow.cpp:initMainWindow() =
Code:
printf("2\n");
database->createTable();
= mymuse/sqlite.cpp =
Code:
bool SQLiteDB
::execQuery(QString queryStr,
bool showError
) {
if(!query.exec(queryStr))
{
queryErr = query.lastError();
if(showError)
{
qApp->tr("%1\n%2")
.arg(lastQueryError(SQL_DB_TEXT))
.arg(lastQueryError(SQL_DRIVER_TEXT)),
}
return false;
}
return true;
}
void SQLiteDB::createTable()
{
execQuery("create table tracks (id integer primary key autoincrement, artist varchar(50), title varchar(80), "
"rating integer, status integer)", true);
execQuery("insert into tracks (artist, title, rating, status) "
"values ('The Rolling Stones', 'Satisfaction', 33, 1)", true);
}
3) Create the relational table model and initialize it:
= mymuse/mainwindow.cpp:initMainWindow() =
Code:
printf("3\n");
database->initModel();
= mymuse/sqlite.cpp =
Code:
void SQLiteDB::initModel()
{
model.setTable("tracks");
model.select();
}
4) Set the QTableView to use the model:
= mymuse/mainwindow.cpp =
Code:
printf("4\n");
database->setView(trackTable);
= mymuse/sqlite.cpp =
Code:
{
table->setModel(tblModel);
}
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.
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?
Re: QTableView from SQLite, empty!
1)
Quote:
Originally Posted by
jacek
Does "model" still exist when you show the table view?
Yes, "model" is defined in the class I use for sql code:
Code:
{
Q_OBJECT
public:
// Constructors and ~Destructors
SQLiteDB();
virtual ~SQLiteDB();
// Public Members
...
};
2)
Quote:
Originally Posted by
jacek
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 =
Code:
class Ui_MainWindow
{
public:
... some widgets ...
... later ...
{
centralwidget
= new QWidget(MainWindow
);
}
};
3)
Quote:
Originally Posted by
jacek
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.
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.
Re: QTableView from SQLite, empty!
Quote:
Originally Posted by
jacek
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:
Code:
void MainWindow::initMainWindow()
{
database.setDatabaseName(dbName);
if(!database.open())
{
QMessageBox::critical(NULL, qApp
->tr
("Cannot open database"),
qApp->tr("Unable to establish a connection with database '%1'.")
.arg(dbName),
return;
}
if(!query.exec("create table tracks (id integer primary key autoincrement, artist varchar(50), "
"title varchar(80), rating integer, status integer)"))
{
printf("Error 1\n");
}
else
{
printf("OK 1\n");
}
if(!query.exec("insert into tracks (artist, title, rating, status) values ('The Rolling Stones', 'Satisfaction', 33, 1)"))
{
printf("Error 2\n");
}
else
{
printf("OK 2\n");
}
if(!query.exec("insert into tracks (artist, title, rating, status) values ('The Doors', 'Riders on the Storm', 75, 1)"))
{
printf("Error 3\n");
}
else
{
printf("OK 3\n");
}
query.next();
model.setTable("tracks");
model.select();
setTable(&model);
}
{
trackTable->setModel(tblModel);
trackTable->show();
}
So now I get a QTableView that looks like this:
Code:
-------------------------------------
| 1 | 2 | 3 | 4 | 5 |
-------------------------------------
1 | | | | | |
-------------------------------------
2 | | | | | |
-------------------------------------
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.
Re: QTableView from SQLite, empty!
Quote:
Originally Posted by
grellsworth
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).
Re: QTableView from SQLite, empty!
Quote:
Originally Posted by
jacek
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?
Re: QTableView from SQLite, empty!
Quote:
Originally Posted by
grellsworth
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.
Re: QTableView from SQLite, empty!
OK, so it should be:
2) Make sure your QSqlRelationalTableModel object doesn't go out of scope.
Re: QTableView from SQLite, empty!
Quote:
Originally Posted by
grellsworth
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.