PDA

View Full Version : Problem showing QTableView



weaver4
22nd November 2009, 20:41
I have the following code inside a pushbutton event. When it runs the data does not show up on the QTableView's grid. There are 74 rows in the model, the "for" statement sends them out to the console correctly.

What am I doing wrong?



void MainWindow::on_pushButton_clicked()
{

DBMgr dbmgr;
if (!dbmgr.OpenDB("moz_downloads","","downloads.sqlite"))
return;

wrkTable = dbmgr.theModel;
ui->tableView->setModel(wrkTable);
ui->tableView->show();

for (int i = 0; i < wrkTable->rowCount(); i++)
{
QSqlRecord r = wrkTable->record(i);
QString s = r.value("Name").toString();
qDebug() << s;
}
}

vieraci
22nd November 2009, 23:10
Is wrkTable a QSqlQueryModel ?

weaver4
22nd November 2009, 23:21
No I am using a QSqlTableModel.

Here is the code. Looking at all the examples they create the db/model before they run the app.exec() routine. Wonder if the data is there but the QTableView is not getting updated.



bool DBMgr::OpenDB(QString tablename, QString filter, QString filename)
{
error = "";
if (!QFile::exists(filename))
{
error = "File does not exist";
return false;
}

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("downloads.sqlite");
qDebug() << "Is Valid:" << db.isValid();
if (!db.open())
{
error = "Unable to open DataBase";
return false;
}

theModel = new QSqlTableModel(NULL,db);
theModel->setTable(tablename);
if (!filter.isEmpty())
theModel->setFilter(filter);
theModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
theModel->select();

qDebug() << "Row Count = " << theModel->rowCount();

return true;
}

vieraci
23rd November 2009, 00:48
I know this works for me:

model = new QSqlTableModel;
view->setModel(model);
model->setQuery(aQuery); // executes the query

weaver4
23rd November 2009, 02:01
Very odd, The vary same code to open the DB and set up a model works in the main line, but when I put it in a method in another class and pass back the Model it fails.

I think it has something to do with the fact if you do the following code the QSqlDatabase and QSqlTAbleModel are magically associated with one another. Even though nothing ties them together. I mean how does the QSqlTableModel know that the "moz_downloads" table is associated with the "downloads.sqlite" database?

And this code does work. But when I take the DB part and the QSqlTableModel and put them in a different class and pass back the QSqlTableModel it fails.



QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("downloads.sqlite");
if (!db.open()) {
qDebug() << "Error opening DB.";
}

QSqlTableModel *qtm = new QSqlTableModel;
qtm->setTable("moz_downloads");
qtm->select();

ui->tableView->setModel(qtm);
ui->tableView->show();

vieraci
23rd November 2009, 14:03
There's no "magic", QSqlDatabase is a static class and anything you do in your app is thru the database you opened with:

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

When you need to access it from your methods, you create an instance of it:

QSqlDatabase db;
db now points to the database you opened at the start, until you close it.

Also, your table model that you created in your method will be destroyed as soon as your method returns, that's why it fails. The correct way is to create the table model from your calling routine and pass it to your function.

weaver4
23rd November 2009, 14:42
My confusion codes from something like this.



QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE");

db.setDatabaseName("downloads.sqlite");
if (!db.open()) {
qDebug() << "Error opening DB.";
}

db2.setDatabaseName("history.sqlite");
if (!db2.open()) {
qDebug() << "Error opening DB.";
}

QSqlTableModel *qtm = new QSqlTableModel;
qtm->setTable("moz_downloads");
qtm->select();


In this case which db is the QSqlTableModel qtm model going to associate the "moz_downloads" table with?

If the table-model was destroyed then it could not print out the records in my button routine could it? But it does.