I have broken the sql/relationaltablemodel example down into four distinct steps:
1) Create the database connection:
= sql/relationaltablemodel/relationaltablemodel.cpp:main() =
if (!createConnection())
return 1;
if (!createConnection())
return 1;
To copy to clipboard, switch view to plain text mode
= sql/connection.h:createConnection() =
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;
}
static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
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"
"Click Cancel to exit."), QMessageBox::Cancel);
return false;
}
return true;
}
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() =
createRelationalTables();
createRelationalTables();
To copy to clipboard, switch view to plain text mode
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)");
}
void createRelationalTables()
{
QSqlQuery query;
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)");
}
To copy to clipboard, switch view to plain text mode
3) Create the relational table model and initialize it:
= sql/relationaltablemodel/relationaltablemodel.cpp:main() =
initializeModel(&model);
QSqlRelationalTableModel model;
initializeModel(&model);
To copy to clipboard, switch view to plain text mode
{
model->setTable("employee");
model->select();
}
void initializeModel(QSqlRelationalTableModel *model)
{
model->setTable("employee");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
}
To copy to clipboard, switch view to plain text mode
4) Set the QTableView to use the model:
= sql/relationaltablemodel/relationaltablemodel.cpp:main() =
QTableView *view = createView(QObject::tr("Relational Table Model"), &model);
To copy to clipboard, switch view to plain text mode
{
view->setModel(model);
view->setWindowTitle(title);
return view;
}
QTableView *createView(const QString &title, QSqlTableModel *model)
{
QTableView *view = new QTableView;
view->setModel(model);
view->setItemDelegate(new QSqlRelationalDelegate(view));
view->setWindowTitle(title);
return view;
}
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() =
database = new SQLiteDB();
printf("1\n");
database->createConnection();
database = new SQLiteDB();
printf("1\n");
database->createConnection();
To copy to clipboard, switch view to plain text mode
= mymuse/sqlite.cpp =
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;
}
bool SQLiteDB::createConnection()
{
QString dbName = ":memory:";
QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
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),
QMessageBox::Cancel);
return false;
}
return true;
}
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() =
printf("2\n");
database->createTable();
printf("2\n");
database->createTable();
To copy to clipboard, switch view to plain text mode
= mymuse/sqlite.cpp =
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);
}
bool SQLiteDB::execQuery(QString queryStr, bool showError)
{
QSqlQuery query;
if(!query.exec(queryStr))
{
queryErr = query.lastError();
if(showError)
{
QMessageBox::critical(NULL, qApp->tr("Query error"),
qApp->tr("%1\n%2")
.arg(lastQueryError(SQL_DB_TEXT))
.arg(lastQueryError(SQL_DRIVER_TEXT)),
QMessageBox::Cancel);
}
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);
}
To copy to clipboard, switch view to plain text mode
3) Create the relational table model and initialize it:
= mymuse/mainwindow.cpp:initMainWindow() =
printf("3\n");
database->initModel();
printf("3\n");
database->initModel();
To copy to clipboard, switch view to plain text mode
= mymuse/sqlite.cpp =
void SQLiteDB::initModel()
{
model.setTable("tracks");
model.select();
}
void SQLiteDB::initModel()
{
model.setTable("tracks");
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.select();
}
To copy to clipboard, switch view to plain text mode
4) Set the QTableView to use the model:
= mymuse/mainwindow.cpp =
printf("4\n");
database->setView(trackTable);
printf("4\n");
database->setView(trackTable);
To copy to clipboard, switch view to plain text mode
= mymuse/sqlite.cpp =
{
table->setModel(tblModel);
}
void SQLiteDB::setView(QTableView *table)
{
QSqlTableModel *tblModel = &model;
table->setModel(tblModel);
table->setItemDelegate(new QSqlRelationalDelegate(table));
}
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.
Bookmarks